首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使clang矢量化一个简单的循环?

如何使clang矢量化一个简单的循环?
EN

Stack Overflow用户
提问于 2019-04-06 02:05:44
回答 2查看 4.1K关注 0票数 3

我有以下循环:

代码语言:javascript
运行
复制
float* s;
float* ap;
float* bp;

... // initialize s, ap, bp

for(size_t i=0;i<64;++i) {
   s[i] = ap[i]+bp[i];
}

似乎是向量化的好人选。尽管启动了优化,但当我查看程序集输出时,clang (我使用的是Xcode)似乎没有将循环向量化:

代码语言:javascript
运行
复制
LBB33_1:                                ## =>This Inner Loop Header: Depth=1
    movss   (%rax,%rsi,4), %xmm0    ## xmm0 = mem[0],zero,zero,zero
    addss   (%rcx,%rsi,4), %xmm0
    movss   %xmm0, (%rdx,%rsi,4)
Ltmp353:
    incq    %rsi
Ltmp354:
    cmpq    $64, %rsi
Ltmp355:
    jne LBB33_1

如何获得clang/Xcode来矢量化这个简单的循环?

EN

回答 2

Stack Overflow用户

发布于 2019-04-06 02:32:13

使用非古代版本的clang/LLVM。Apple /LLVM与主线clang/LLVM不同,但它们有一个共同的代码库。

主线clang3.3和更新的自动矢量化循环在-O3.-O2**.** Clang3.4和更新版本的自动矢量化

如果没有restrict,clang就会发出asm,以检查目标和两个源之间的重叠(返回到标量),因此您将从float *restrict s获得更有效的asm。

代码语言:javascript
运行
复制
#include <stdlib.h>
void add_float_good(float *restrict s, float *restrict ap, float *restrict bp)
{
    for(size_t i=0;i<64;++i) {
       s[i] = ap[i]+bp[i];
    }
}

用最糟糕的索引寻址模式和循环开销将使用clang3.4-O3(在戈德波特编译器浏览器上)编译到这个简单的asm中,但至少它是向量化的。较新的clang喜欢展开,特别是在为最近的英特尔(如-march=skylake)进行调优时。

代码语言:javascript
运行
复制
# clang3.4 -O3
add_float_good:
        xor     eax, eax
.LBB0_1:                                # %vector.body
        movups  xmm0, xmmword ptr [rsi + 4*rax]
        movups  xmm1, xmmword ptr [rdx + 4*rax]
        addps   xmm1, xmm0
        movups  xmmword ptr [rdi + 4*rax], xmm1
        add     rax, 4
        cmp     rax, 64
        jne     .LBB0_1
        ret

注意,如果没有AVX,它就不能为addps使用内存源操作数,因为没有编译时对齐的保证。

clang8.0 -O3 -march=skylake完全使用YMM向量展开,就像gcc具有相同的选项。

票数 12
EN

Stack Overflow用户

发布于 2019-04-06 02:13:35

最好是使用“加速”来明确这一点。在这种情况下,vDSP_vadd会做到这一点。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55545231

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档