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

5412                                                      软件学报  2025  年第  36  卷第  12  期


                    同时, 我们在    SACA.jl 中还实现了针对存储管理、异步传输、线程索引及阵列同步等功能的运行时                           API 封
                 装, 其与  SACA C API 的对应关系如表     3  所示. 在  SACA C  中, 考虑到用户编程的便捷性和高效性, 运行时           API 的
                 实现方式较为灵活. 例如, 存储空间管理既支持通过__ldm/__cross 等关键字静态声明, 也支持通过                      ldm_malloc 等
                 接口动态分配, 而同步等对性能要求较高的接口则采用嵌汇编方式实现.

                                      表 3 Julia 运行时  API 封装及与   SACA C API 的对应关系

                  类型                      Julia API                              SACA C API
                             SACAShareLDMArray(::Type{T}, dims::Tuple)           __ldm_share
                               SACACrossArray(::Type{T}, dims::Tuple)              __cross
                 存储管理
                             SACAStaticLDMArray(::Type{T}, dims::Tuple)             __ldm
                            SACADynamicLDMArray(::Type{T}, dims::Tuple)      void* ldm_malloc(size_t)
                        SACADMAGet(mem_addr::Ptr{Cvoid}, ldm_addr:: Ptr{Cvoid}, void athread_dma_get(void *mem_addr, void *ldm_addr,
                                         len::Integer)                             int len)
                 异步传输
                        SACADMAPut(mem_addr::Ptr{Cvoid}, ldm_addr:: Ptr{Cvoid}, void athread_dma_put(void *mem_addr, void *ldm_addr,
                                         len::Integer)                             int len)
                                           _PEN()                                   _PEN
                                          _CGN()                                    _CGN
                 线程索引                     _ROW()                                   _ROW
                                           _COL()                                   _COL
                                          _MYID()                                  _MYID
                                   sync_row(mask::Integer=0xff)                CRTS_ssync_row()
                 阵列同步              sync_col(mask::Integer=0xff)                 CRTS_ssync_col()
                                   sync_array(mask::Integer=0xff)              CRTS_ssync_array()
                    在  SACA.jl 的运行时  API 封装实现中, 我们沿袭了       SACA C  的设计理念, 针对不同接口的功能特性采取了多
                 样化的实现策略. 图      11  展示了  SACA.jl 运行时  API 封装的  3  个典型范例. 对于诸如   SACAStaticLDMArray  等静态
                 存储空间管理接口, 我们巧妙地运用了@generated           宏, 使得在编译阶段便能根据函数参数类型动态生成专属代码.
                 这种方法相较于传统的函数定义方式, 展现了一种更为灵活且高效的多重分派机制. 在处理诸如同步等实现简洁
                 且需频繁调用的接口时, 我们借助           LLVM.jl 提供的@asmcall 宏进行定义. 通过@asmcall, Julia 代码能够直接生成
                 底层的汇编指令, 从而显著减少因多层函数调用而产生的额外运行开销. 对于其他常规的运行时接口, 例如
                 SACADMAGet, 我们采用    ccall 方法直接生成   LLVM IR  层的外部函数调用, 在保证代码简洁高效的同时确保与底
                 层系统的顺畅交互. 上述多样化的实现方案不仅有效继承了                    SACA C  运行时接口的灵活性, 更在最大程度上减少
                 了对  Julia 编译器的底层修改需求, 从而确保了整个系统的稳定性和高效性.

























                                           图 11 Julia 运行时  API 封装的实现方式示例
   26   27   28   29   30   31   32   33   34   35   36