Купил HP ноутбук с i5. На третий день вдруг обнаружил в отладчике опцию показывать ymm регистры. “Да ну, не может быть. Наверное, MS в студии свою готовность демонстрирует” - подумал я. Показалось, что слишком мало времени прошло. Но первый же результат google-поиска i5 2410M подтвердил - Sandy Bridge. Надо проверять. Следующий код
int cpu[4];
__cpuid(cpu,1);
printf("CPU: %sSSE2,%sSSE3,%sSSSE3,%sSSE4,%sSSE42,"
"%sSSE4a,%sAVX,%sAVXFMA\n",
cpu[3]&0x04000000?"+":"-",
cpu[2]&0x00000001?"+":"-",
cpu[2]&0x00000200?"+":"-",
cpu[2]&0x00080000?"+":"-",
cpu[2]&0x00100000?"+":"-",
cpu[2]&0x00000040?"+":"-", /// :)
(cpu[2]&0x18000000)==0x18000000?"+":"-",
(cpu[2]&0x18001000)==0x18001000?"+":"-");
подтвердил, имею AVX
CPU: +SSE2,+SSE3,+SSSE3,+SSE4,+SSE42,-SSE4a,+AVX,-AVXFMA
Супер!
__cpuid(cpu,1);
printf("CPU: %sSSE2,%sSSE3,%sSSSE3,%sSSE4,%sSSE42,"
"%sSSE4a,%sAVX,%sAVXFMA\n",
cpu[3]&0x04000000?"+":"-",
cpu[2]&0x00000001?"+":"-",
cpu[2]&0x00000200?"+":"-",
cpu[2]&0x00080000?"+":"-",
cpu[2]&0x00100000?"+":"-",
cpu[2]&0x00000040?"+":"-", /// :)
(cpu[2]&0x18000000)==0x18000000?"+":"-",
(cpu[2]&0x18001000)==0x18001000?"+":"-");
подтвердил, имею AVX
CPU: +SSE2,+SSE3,+SSSE3,+SSE4,+SSE42,-SSE4a,+AVX,-AVXFMA
Супер!
В действительности этой проверки недостаточно, надо проверять xgetbv, чтобы узнать, поддерживает ли OS AVX, смотри Intel документ 319433-011. Проверил доступность AVX в Ubuntu (которую установил на ноутбуке, как вторую OS) простым “cat /proc/cpuinfo”, - доступны.
Пишем что-нибудь проверить производительность, например axpy Y=Y+a*X. Для начала в 32 битном режиме. Сравниваем производительность AVX кода
@@by8:
vmulps ymm0, ymm1, REAL4 PTR [esi+ecx*4-32]
vaddps ymm2, ymm0, REAL4 PTR [eax+ecx*4-32]
vmovaps REAL4 PTR [eax+ecx*4-32], ymm2
sub ecx, 8
jg @@by8
с кодом SSE2, который почти такой же, но двух-местный. Константу размножаем вместо pshufd новой инструкцией vbroadcastss и данные выравниваем не на 16, а на 32 байта. Ускорение есть, хоть и скромное.
vmulps ymm0, ymm1, REAL4 PTR [esi+ecx*4-32]
vaddps ymm2, ymm0, REAL4 PTR [eax+ecx*4-32]
vmovaps REAL4 PTR [eax+ecx*4-32], ymm2
sub ecx, 8
jg @@by8
с кодом SSE2, который почти такой же, но двух-местный. Константу размножаем вместо pshufd новой инструкцией vbroadcastss и данные выравниваем не на 16, а на 32 байта. Ускорение есть, хоть и скромное.
Правильность результата тоже проверена.
Будем использовать, там, где ускорения можно ждать. Хорош ноутбук!
No comments:
Post a Comment