Page 28 - 《软件学报》2025年第12期
P. 28

沈莉 等: swJulia: 面向新一代神威超级计算机的         Julia 语言编译系统                               5409



                 算法  1. !ldmhigh/!ldmlow  重定位修正算法.
                 输入: 动态库的重定位表       relaTable 以及.ldm  段  LDMSec;
                 输出: 重定位修正后的动态库代码段           text.

                 1. ldm_pstart = mmap(LDMSec.getSize(), FLAG_LDM)
                 2. FOR rela∈relaTable DO
                 3.   IF rela.getType()∈{R_SW_64_LDMHI, R_SW_64_LDMLO} THEN
                 4.     offset = rela.getSym().getVAddr() – LDMSec.getVAddr()
                 5.     ldm_paddr = ldm_pstart + offset
                 6.     IF rela.getType() == R_SW_64_LDMLO THEN
                 7.       disp = ldm_paddr & 0xFFFF
                 8.     ELSE
                 9.       carry = (ldm_paddr >> 15) & 0x1
                 10.        disp = ((ldm_paddr >> 16) + carry) & 0xFFFF
                 11.       END IF
                 12.       rela.getInstr(text).fixOffset(disp)
                 13.   END IF
                 14. END FOR

                    该方案通过改进       swLLVM  编译器及其配套的二进制工具链, 既规避了             LDM  变量潜在的地址冲突问题, 保证
                 了  LLVM IR  向  CPE  汇编指令降级的正确性, 又实现了对片上存储空间的高效访问, 为                swJulia 的动态运行提供了
                 稳定的底层支撑.
                  2.3   SACA.jl
                    SACA (Sunway accelerate computing architecture) 是面向申威众核架构的并行加速计算编程模型, 其优化整合
                 了基础编译及运行时等编程接口, 为科学计算、人工智能等领域应用提供统一的编程和优化支持                                 [23] . SACA.jl 是
                 为了在   Julia 语言中支持  SACA  编程模型而开发的第三方库. 其为          Julia 开发者提供了一种便捷和高效的方式来利
                 用  SW26010Pro  进行计算加速, 无需用户深入了解        SACA  的底层细节, 降低了学习和开发成本.
                    SACA.jl 实际上由两个主要组件组成: CPE          编译器负责将      Julia  源代码转换为   CPE  上可执行的机器代码,
                 SACA  封装则提供了在     CPE  上执行常用操作所需的类型和接口. 本文基于              Julia 社区已有的基础设施, 在不改动
                 Julia 编译器底层实现的前提下, 通过        SACA.jl 实现了  Julia 语言对  SACA  编程模型的支持. SACA.jl 支持    Julia 语
                 言的一个子集, 但是已经证明能够满足            SW26010Pro  应用开发的现实需求.
                  2.3.1    CPE  编译器
                    图  7  展示了在  C  语言中使用   SACA API 进行向量加法的示例, 包括线程初始化、线程组创建、线程等待及
                 线程回收等. 其中, athread_init 接口用于进行线程的初始化操作, 使用任何              SACA  接口前都需要调用该初始化接
                 口. athread_spawn  接口用于创建线程组并传递运行参数, 其指定的线程任务将被提交到                    CPE  阵列执行. athread_
                 join  接口用于等待  CPE  阵列的加速线程任务结束, 而        athread_halt 接口则用于关闭  CPE  流水线.
                    SACA.jl 通过  CPE  编译器支持对   Julia 函数的编译, 从而实现与     SACA C  类似的程序语义. 图     8  展示了一个基
                 于  SACA.jl 实现的  Julia 语言向量加法程序示例, 该程序的功能与图           7  中展示的   C  语言版本完全相同. 代码的第
                 2–7  行定义了一个名为     vadd  的  Kernel 函数, 该函数的风格与普通    Julia 函数相似, 但在计算迭代索引变量        i 时特别
                 采用了   SACA.jl 的内建函数_MYID(), 以获取当前      CPE  的逻辑编号. 与    CUDA  或  OpenCL  等异构编程模型相比,
                 SACA.jl 的一个显著优势在于, 它无需用户对          Kernel 进行显式的注释或封装, 从而显著提升了代码的可重用性. 在
                 代码的第   14  行, 程序通过@saca (config…) function(args…) 接口调用了  Kernel 函数. 这里的  config  元组用于指定
   23   24   25   26   27   28   29   30   31   32   33