Как получить компилятор ICC для генерации инструкций SSE во внутреннем цикле? - PullRequest
2 голосов
/ 06 июля 2011

У меня есть внутренний цикл, такой как этот

for(i=0 ;i<n;i++){
 x[0] += A[i] * z[0];
 x[1] += A[i] * z[1];
 x[2] += A[i] * z[2];
 x[3] += A[i] * z[3];
}

Внутренние 4 инструкции могут быть легко преобразованы в инструкции SSE компилятором. Текущие компиляторы делают это? Если они делают то, что я должен сделать, чтобы заставить это на компиляторе?

Ответы [ 2 ]

4 голосов
/ 06 июля 2011

Из того, что вы предоставили, это не может быть векторизовано, потому что указатели могут быть псевдонимами друг друга, то есть массив x может перекрываться с A или z.

Простой способ помочь компилятору - объявить x как __restrict. Другим способом было бы переписать его так:

for(i=0 ;i<n;i++)
{
 float Ai=A[i];
 float z0=z[0], z1=z[1], z2=z[2], z3=z[3];
 x[0] += Ai * z0;
 x[1] += Ai * z1;
 x[2] += Ai * z2;
 x[3] += Ai * z3;
}

На самом деле я никогда не пытался заставить компилятор автоматически векторизовать код, поэтому я не знаю, сделает это это или нет. Даже если он не будет векторизован, он должен быть быстрее, поскольку нагрузки и хранилища могут быть упорядочены более эффективно и не вызывая загрузку хранилища.

Если у вас есть больше информации, чем у компилятора (например, выровнены ли ваши 16-байтовые указатели), и вы должны иметь возможность использовать это в своих интересах (например, с помощью выровненных нагрузок). Обратите внимание, что я не говорю, что вы всегда должны пытаться побить компилятор, только когда вы знаете больше, чем он.

Дальнейшее чтение:

0 голосов
/ 07 мая 2014

ICC автоматически векторизирует приведенный ниже фрагмент кода для SSE2 по умолчанию:

void foo(float *__restrict__ x, float *__restrict__ A, float *__restrict__ z, int n){
for(int i=0;i<n;i++){
 x[0] += A[i] * z[0];
 x[1] += A[i] * z[1];
 x[2] += A[i] * z[2];
 x[3] += A[i] * z[3];
}
return;
}

При использовании ключевого слова restrict предположение о псевдониме памяти игнорируется. Создан отчет о векторизации:

$ icpc test.cc -c -vec-report2 -S
test.cc(2): (col. 1) remark: PERMUTED LOOP WAS VECTORIZED
test.cc(3): (col. 2) remark: loop was not vectorized: not inner loop

Чтобы подтвердить, генерируются ли инструкции SSE, откройте сгенерированный ASM (test.s), и вы найдете следующие инструкции:

..B1.13:                        # Preds ..B1.13 ..B1.12
        movaps    (%rsi,%r15,4), %xmm10                         #3.10
        movaps    16(%rsi,%r15,4), %xmm11                       #3.10
        mulps     %xmm0, %xmm10                                 #3.17
        mulps     %xmm0, %xmm11                                 #3.17
        addps     %xmm10, %xmm9                                 #3.2
        addps     %xmm11, %xmm6                                 #3.2
        movaps    32(%rsi,%r15,4), %xmm12                       #3.10
        movaps    48(%rsi,%r15,4), %xmm13                       #3.10
        movaps    64(%rsi,%r15,4), %xmm14                       #3.10
        movaps    80(%rsi,%r15,4), %xmm15                       #3.10
        movaps    96(%rsi,%r15,4), %xmm10                       #3.10
        movaps    112(%rsi,%r15,4), %xmm11                      #3.10
        addq      $32, %r15                                     #2.1
        mulps     %xmm0, %xmm12                                 #3.17
        cmpq      %r13, %r15                                    #2.1
        mulps     %xmm0, %xmm13                                 #3.17
        mulps     %xmm0, %xmm14                                 #3.17
        addps     %xmm12, %xmm5                                 #3.2
        mulps     %xmm0, %xmm15                                 #3.17
        addps     %xmm13, %xmm4                                 #3.2
        mulps     %xmm0, %xmm10                                 #3.17
        addps     %xmm14, %xmm7                                 #3.2
        mulps     %xmm0, %xmm11                                 #3.17
        addps     %xmm15, %xmm3                                 #3.2
        addps     %xmm10, %xmm2                                 #3.2
        addps     %xmm11, %xmm1                                 #3.2
        jb        ..B1.13       # Prob 75%                      #2.1
                                # LOE rax rdx rsi r8 r9 r10 r13 r15 ecx ebp edi r11d r14d bl xmm0 xmm1 xmm2 xmm3 xmm4 xmm5 xmm6 xmm7 xmm8 xmm9
..B1.14:                        # Preds ..B1.13
        addps     %xmm6, %xmm9                                  #3.2
        addps     %xmm4, %xmm5                                  #3.2
        addps     %xmm3, %xmm7                                  #3.2
        addps     %xmm1, %xmm2                                  #3.2
        addps     %xmm5, %xmm9                                  #3.2
        addps     %xmm2, %xmm7                                  #3.2
        lea       1(%r14), %r12d                                #2.1
        cmpl      %r12d, %ecx                                   #2.1
        addps     %xmm7, %xmm9                                  #3.2
        jb        ..B1.25       # Prob 50%                      #2.1
...