为什么 numba 这么快?

互联网 行业动态 更新时间:2024-06-13 00:19:07

Jér*_*ard 6

Numba 目前使用 LLVM-Lite 将代码高效地编译为二进制文件(在 Python 代码被转换为 LLVM 中间表示之后)。代码经过优化,就像 C++ 代码将使用带有标志的 Clang-O3-march=native. 最后一个参数非常重要,因为它使 LLVM 能够在相对较新的 x86-64 处理器上使用更广泛的 SIMD 指令:AVX 和 AVX2(对于最近的英特尔处理器可能是 AVX512)。否则,默认情况下 Clang 和 GCC 仅使用 SSE/SSE2 指令(因为向后兼容)。

另一个区别来自 GCC 和 Numba 的 LLVM 代码之间的比较。Clang/LLVM 倾向于积极展开循环,而 GCC 通常不会。这对生成的程序有显着的性能影响。实际上,您可以看到从 Clang 生成的汇编代码:

使用 Clang(每个循环 128 个项目):

.LBB0_7:
        vmovups ymmword ptr [r9 + 4*r8 - 480], ymm0
        vmovups ymmword ptr [r9 + 4*r8 - 448], ymm0
        vmovups ymmword ptr [r9 + 4*r8 - 416], ymm0
        vmovups ymmword ptr [r9 + 4*r8 - 384], ymm0
        vmovups ymmword ptr [r9 + 4*r8 - 352], ymm0
        vmovups ymmword ptr [r9 + 4*r8 - 320], ymm0
        vmovups ymmword ptr [r9 + 4*r8 - 288], ymm0
        vmovups ymmword ptr [r9 + 4*r8 - 256], ymm0
        vmovups ymmword ptr [r9 + 4*r8 - 224], ymm0
        vmovups ymmword ptr [r9 + 4*r8 - 192], ymm0
        vmovups ymmword ptr [r9 + 4*r8 - 160], ymm0
        vmovups ymmword ptr [r9 + 4*r8 - 128], ymm0
        vmovups ymmword ptr [r9 + 4*r8 - 96], ymm0
        vmovups ymmword ptr [r9 + 4*r8 - 64], ymm0
        vmovups ymmword ptr [r9 + 4*r8 - 32], ymm0
        vmovups ymmword ptr [r9 + 4*r8], ymm0
        sub     r8, -128
        add     rbp, 4
        jne     .LBB0_7

使用 GCC(每个循环 8 个项目):

.L5:
        mov     rdx, rax
        vmovups YMMWORD PTR [rax], ymm0
        add     rax, 32
        cmp     rdx, rcx
        jne     .L5

因此,公平地说,您需要将 Numba 代码与使用 Clang 和上述优化标志编译的 C++ 代码进行比较。


请注意,根据您的需求和最后一级处理器缓存的大小,您可以使用非临时存储(NT 存储)编写更快的特定于平台的 C++ 代码。NT 存储告诉处理器不要将数组存储在其缓存中。使用 NT 存储写入数据可以更快地在 RAM 中写入巨大的数组,但是当您在复制后读取存储的数组时,如果数组可以放入缓存中,则速度会变慢(因为必须从 RAM 重新加载数组)。在您的情况下(4 MiB 阵列),这是否会更快尚不清楚。

更多推荐

numba

本文发布于:2023-04-20 21:02:12,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/hyzx/15bb2f3d507c71ae5ad7ac92bbd2b799.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:numba

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!