Задать вопрос
@mlyamasov

Почему время выполнения следующих SIMD инструкций такое?

Пытаюсь разобраться с векторизацией, написал такую простенькую программку:
#include <stdio.h>

int main()
{
    unsigned int i;
    double x1, x2, x3, x4, y1, y2, y3, y4;
    x1 = 1.0000000001;
    x2 = 1.0000000002;
    x3 = 1.0000000003;
    x4 = 1.0000000004;
    y1 = x1;
    y2 = x2;
    y3 = x3;
    y4 = x4;
    for (i = 0; i < 3640000000; i++) {
        y1 *= x1;
        y2 *= x2;
        y3 *= x3;
        y4 *= x4;
    }
    printf("%g %g %g %g\n", y1, y2, y3, y4);
}

Архитектура: i686.
Опции gcc: -O1. 4 инструкции fmul в цикле. Время выполнения: 10с.

11d4:       fxch   %st(4)
11d6:       fxch   %st(3)
11d8:       fxch   %st(2)
11da:       fmul   %st,%st(1)
11dc:       fxch   %st(2)
11de:       fmull  -0x1fd8(%ebx)
11e4:       fxch   %st(3)
11e6:       fmull  -0x1fe0(%ebx)
11ec:       fxch   %st(4)
11ee:       fmull  -0x1fe8(%ebx)
11f4:       sub    $0x1,%eax
11f7:       jne    11d4 <__cxa_finalize@plt+0x184>


Опции gcc: -O1 -mfpmath=sse -msse2. 4 инструкции mulsd в цикле. Время выполнения: 6.7с.

11e8:       mulsd  %xmm7,%xmm0
11ec:       mulsd  %xmm6,%xmm1
11f0:       mulsd  %xmm5,%xmm2
11f4:       mulsd  %xmm4,%xmm3
11f8:       sub    $0x1,%eax
11fb:       jne    11e8 <__cxa_finalize@plt+0x198>


Опции gcc: -O1 -mfpmath=sse -mavx. 4 инструкции vmulsd в цикле. Время выполнения: 6.7с.

11e8:       vmulsd %xmm7,%xmm0,%xmm0
11ec:       vmulsd %xmm6,%xmm1,%xmm1
11f0:       vmulsd %xmm5,%xmm2,%xmm2
11f4:       vmulsd %xmm4,%xmm3,%xmm3
11f8:       sub    $0x1,%eax
11fb:       jne    11e8 <__cxa_finalize@plt+0x198>


Опции gcc: -O1 -mfpmath=sse -msse2 -ftree-vectorize. 2 инструкции mulpd в цикле. Время выполнения: 6.7с.

11d0:       mulpd  %xmm3,%xmm1
11d4:       mulpd  %xmm2,%xmm0
11d8:       add    $0x1,%eax
11db:       cmp    $0xd8f5fe00,%eax
11e0:       jne    11d0 <__cxa_finalize@plt+0x180>


Опции gcc: -O1 -mfpmath=sse -mavx -ftree-vectorize. 1 инструкция vmulpd в цикле. Время выполнения: 6.7с.

11c7:       vmulpd %ymm1,%ymm0,%ymm0
11cb:       add    $0x1,%eax
11ce:       cmp    $0xd8f5fe00,%eax
11d3:       jne    11c7 <__cxa_finalize@plt+0x177>


Почему пятый вариант не выполняется в 4 раза быстрее, чем первый? Что можно почитать на эту тему?
  • Вопрос задан
  • 103 просмотра
Подписаться 2 Простой 1 комментарий
Решения вопроса 1
jcmvbkbc
@jcmvbkbc
"I'm here to consult you" © Dogbert
Я не нашёл ничего почитать, но нашёл рекомендацию использовать llvm-mca, и для вариантов кода использующих SSE/AVX она дала мне показатели производительности которые совпали с наблюдаемыми на практике. Cоответственно, при желании можно почитать исходники llvm-mca (и добраться до модели пайплайна где-то в недрах llvm).

Почему пятый вариант не выполняется в 4 раза быстрее, чем первый?

Потому что скорость выполнения связана со сложностью опкодов. Так, выполнение vmulpd в пятом варианте занимает 4 такта и полностью перекрывается с остальными инструкциями цикла, так что даже нет смысла делать его короче, меняя add+cmp+jne на sub+jne.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы