写点什么

开源之夏 | 【结项报告】毕昇 Fortran 编译器内联动态库函数 str_copy

作者:openEuler
  • 2022 年 9 月 27 日
    新加坡
  • 本文字数:1626 字

    阅读完需:约 5 分钟

文章来源于毕昇编译 ,作者王哲葳


项目简介

  • 项目名称

  • 毕昇 Fortran 编译器内联动态库函数 str_copy

  • 项目描述

  • 毕昇 Fortran 编译器是一款基于 classic flang 的高性能 Fortran 编译器,支持 Fortran 编程语言的编译和运行,提供强大的数值计算和数据处理能力,在科学计算领域应用前景广阔。f90_str_copy_klen 是一个实现字符串拷贝功能的动态库函数,本项目是对该动态库函数进行内联,预期提高编译器字符串拷贝的性能。

  • 项目导师

  • peixin-qiao

  • 项目开发者

  • 王哲葳,华东师范大学硕士在读

  • 项目链接

  • https://summer-ospp.ac.cn/#/org/prodetail/22b970386

开发详情

01 方案描述

Flang 编译器主要由 flang1 和 flang2 两个组件组成,其中 flang1 用于解析 Fortran 代码并生成中间表示,然后通过 flang2 生成 LLVM IR 并输出。本项目的主要任务就是在 flang2 中对解析出的“f90_str_copy_klen”函数进行内联优化。这个项目的方案分为如下几步:


步骤一


flang2 会获得通过 Fortran 生成的 IR 指令列表,遍历该列表,寻找到函数调用指令“I_CALL”。


步骤二


通过“I_CALL”指令的位置查询所调用的是否为需要被内联的函数,如本项目需要实现的“f90_str_copy_klen”函数的内联。在确认需要内联的函数后开始生成相应的指令,“f90_str_copy_klen”函数的内联指令生成过程如下:


  1. 将复制后得到的字符串称为目标字符串,待复制的字符串称为输入字符串。首先需要从原先的指令中获得输入字符串并开辟一系列内存空间用于记录目标字符串、输入字符串的起始地址、字符串索引及字符串长度。

  2. 对每一个输入字符串,从头开始遍历。分别判断当前目标字符串、输入字符串的索引是否小于其长度,如果均符合则将输入字符串中对应索引的字符复制到目标字符串的相应地址中。如果输入字符串索引大于等于其长度则处理下一个输入字符串。如果目标字符串索引大于等于其长度则停止字符串的复制。

  3. 按照 2 所述流程依次遍历函数中的输入字符串,直至所有字符串都完成复制。

  4. 目标字符串索引是否仍小于其长度,若是,则将目标字符串中剩余未被赋值的字符用空格进行补充。

  5. 将实现上述功能的指令替换掉对应的“I_CALL”指令。


步骤三


继续 flang2 中的流程以生成对应的 LLVM IR 文件。

项目产出

  • [√ ] 实现了项目方案中所需的功能。

  • [√ ] 分别用一个字符串、三个字符串作为输入字符串,完成了共十种输入字符串各种长度情况下”f90_str_copy_klen”函数内联的的功能性测试,在这些输入字符串中也包含了一些 ASCII 码小于 32(ASCII 码为 32 表示空格)的特殊字符。十种情况如下:

  • a=b

  • len(a) < len(b)len(a) = len(b)len(a) > len(b)

  • a = b // c // d

  • len(a) < len(b)len(a) = len(b)len(b) < len(a) < len(b) + len(c)len(a) = len(b) + len(c)len(b) + len(c) < len(a) < len(b) + len(c) + len(d)len(a) = len(b) + len(c) + len(d)


len(a) > len(b) + len(c) + len(d)


  • [√ ] 将“f90_str_copy_klen”在函数中调用一亿次,对内联前后所花费的时间做对比。实验结果显示没有内联时运行花费的时间约为 10 秒,内联后运行花费的时间约为 0.7 秒。

  • 测试代码如下:主函数:main.f90


program main  integer :: i  character(20) :: a, b, c, d  a = "aaaaaaaaaaaaaaa"  b = "aaaaaaaaaaaaaaa"  c = "aaaaaaaaaaaaaaa"  do i = 1, 100000000    call test(a, b, c, d, 20)  enddoend
复制代码


字符串拼接拷贝函数:test.f90


subroutine test(a, b, c, d, n)  integer :: n  character(n) :: a, b, c, d  d = a // b // cend subroutine
复制代码


  • 测试方法如下: 未优化前:


$ flang main.f90 -c$ flang test.f90 -O3 -c$ flang main.o test.o -o a.out$ time ./a.out
复制代码


real 0m10.190suser 0m10.180ssys 0m0.004s


优化之后(编译选项-Mx,218,0x1 使能该优化功能):


$ flang main.f90 -c$ flang test.f90 -O3 –c –Mx,218,0x1$ flang main.o test.o -o a.out$ time ./a.out
复制代码


real 0m0.706suser 0m0.702ssys 0m0.004s




除开源之夏外,Compiler SIG 还发布了十多个开源实习任务,欢迎各位高校生报名参与~


https://www.openeuler.org/zh/internship/


用户头像

openEuler

关注

还未添加个人签名 2020.09.30 加入

开源操作系统 openEuler 是由开放原子开源基金会(OpenAtom Foundation)孵化及运营的开源项目

评论

发布
暂无评论
开源之夏 | 【结项报告】毕昇Fortran编译器内联动态库函数str_copy_开源_openEuler_InfoQ写作社区