在编译时检测 CPU 功能并对其进行“调度”

Dan*_*etz 5 llvm julia

是否可以编写一个根据 Julia/LLVM 编译目标使用不同算法的函数?

目标是在编译时执行此操作,并希望使该函数可内联。

只是为了有一些代码,这可能看起来像:

function do_it()
    if (CPU_has_avx512) # resolved at compile. code for one branch generated
        ...
    else
        ...
    end
end
Run Code Online (Sandbox Code Playgroud)

Prz*_*fel 2

您可以创建以下宏:

using CpuId
macro cpuf(what)
    quote
        $(CpuId.cpufeature(what.value))
    end
end
Run Code Online (Sandbox Code Playgroud)

这显然在编译时用固定值替换了调用:

julia> @macroexpand @cpuf(:AVX)
quote
    #= REPL[75]:3 =#
    true
end
Run Code Online (Sandbox Code Playgroud)

现在我们可以调度类型Val

f1(::Val{true}) = 100
f1(::Val{false}) = -100
Run Code Online (Sandbox Code Playgroud)
julia> f1(Val{@cpuf(:AVX)}())
100
Run Code Online (Sandbox Code Playgroud)

这一切都会按照您的意愿编译:

julia> @code_llvm f1(Val{@cpuf(:AVX)}())
;  @ REPL[89]:1 within `f1`
; Function Attrs: uwtable
define i64 @julia_f1_935() #0 {
top:
  ret i64 100
}
Run Code Online (Sandbox Code Playgroud)

  • “code”块内的“$”使该代码在编译时执行。我相信这可以是任何 Julia 代码,并且此类代码将在编译期间执行(当然,在某些角落场景中,我们可能会遇到世界年龄问题等)。所以“cpufeature”在任何方面都没有什么特殊之处。关于现在使用机器相关计算的地方 - 我不知道。我怀疑 libblastrampoline 项目可能会在这方面发生有趣的事情。基本上,在大多数情况下,人们希望进行可复制的科学实验,而不是依赖于平台的代码。 (2认同)