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 封装的实现方式示例

