Почему Visual Studio увеличивает указатель цикла перед разыменованием его?

Я проверил выходные данные сборки Visual Studio 2012 из следующего кода SIMD:

    float *end = arr + sz;
float *b = other.arr;
for (float *a = arr; a < end; a += 4, b += 4)
{
__m128 ax = _mm_load_ps(a);
__m128 bx = _mm_load_ps(b);
ax = _mm_add_ps(ax, bx);
_mm_store_ps(a, ax);
}

Тело цикла:

$LL11@main:
movaps  xmm1, XMMWORD PTR [eax+ecx]
addps   xmm1, XMMWORD PTR [ecx]
add ecx, 16                 ; 00000010H
movaps  XMMWORD PTR [ecx-16], xmm1
cmp ecx, edx
jb  SHORT $LL11@main

Зачем увеличивать ecx на 16, только вычесть 16 при сохранении к нему следующей строки?

7

Решение

Ну, в основном здесь есть два варианта.

 add ecx, 16
movaps XMMWORD PTR [ecx-16], xmm1 ; stall for ecx?
cmp ecx, edx
jb loop

или же

 movaps XMMWORD PTR [ecx], xmm1
add ecx, 16
cmp ecx, edx ; stall for ecx?
jb loop

В варианте 1 у вас есть потенциальная остановка между add а также movaps, В варианте 2 у вас есть потенциальная остановка между add а также cmp, Однако существует также проблема используемого исполнительного блока. add а также cmp знак равноsub) используйте АЛУ, в то время как [ecx-16] Я думаю, что использует AGU (Address Generation Unit). Поэтому я подозреваю, что в варианте 1 возможен небольшой выигрыш, поскольку использование ALU чередуется с использованием AGU.

7

Другие решения

Задержка ADDPS составляет 3 цикла, плюс загрузка памяти, поэтому следующий ADD, который выполняется намного быстрее, завершится до того, как может запуститься следующий MOVAPS, которому необходим результат ADDPS в регистре xmm1.

4

На самом деле это немного странно.

Многие компиляторы избегают читать регистр в инструкции после ее изменения, потому что такой код работает медленнее на некоторых процессорах. Пример:

; Code that runs fast:
add ecx, 16
mov esi, edi
cmp ecx, edx

; Code doing the same that may run slower:
mov esi, edi
add ecx, 16
cmp ecx, edx

По этой причине компиляторы часто меняют порядок инструкций ассемблера. Однако в вашем случае это определенно не причина.

Возможно, код оптимизации компилятора не написан на 100% правильно, и поэтому он выполняет такую ​​«оптимизацию».

1
По вопросам рекламы [email protected]