Как я могу заставить Clang векторизовать простой цикл? - PullRequest
1 голос
/ 06 апреля 2019

У меня есть следующий цикл:

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), похоже, не векторизовал цикл:

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векторизовать этот простой цикл?

Ответы [ 2 ]

6 голосов
/ 06 апреля 2019

Используйте не древнюю версию clang / LLVM .Apple clang / LLVM отличается от mainline clang / LLVM, но они имеют общую кодовую базу.

Mainline clang3.3 и новее автоматически векторизуют ваш цикл на -O3. Clang3.4 и более новые автоматически векторизируют его даже при -O2.

Без restrict, clang делает испускает asm, который проверяет перекрытие между пунктом назначения идва источника (с откатом к скаляру), так что вы получите более эффективный asm из float *restrict s.

#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 (в проводнике компилятора Godbolt) к этому упрощенному асму с худшим из индексированных режимов адресации и накладных расходов цикла, но по крайней мере он векторизован.Новому clang нравится разворачиваться, особенно при настройке на последние версии Intel (например, -march=skylake)

# 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 с теми же параметрами.

0 голосов
/ 06 апреля 2019

Вероятно, лучше сделать это явно, используя Accelerate. В этом случае vDSP_vadd сделает свое дело.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...