Когда данные перемещаются между регистрами SSE и стеком?

Я не совсем уверен, что происходит, когда я вызываю _mm_load_ps? Я имею в виду, я знаю, что я загружаю массив из 4 чисел с плавающей запятой в __m128, который я могу использовать для выполнения ускоренной арифметики SIMD, а затем сохранить их обратно, но это не __m128 данных введите все еще в стеке? Я имею в виду, очевидно, не хватает регистров для загрузки произвольного количества векторов. Так что эти 128 бит данных перемещаются вперед и назад каждый раз, когда вы используете какую-либо SIMD-инструкцию для выполнения вычислений? Если так, чем смысл _mm_load_ps?

Может у меня все неправильно?

2

Решение

Процессор Intel с SSE, AVX или AVX-512 может иметь от 8 до 32 SIMD-регистров (см. Ниже). Количество регистров также зависит от того, является ли это 32-битным или 64-битным кодом. Поэтому, когда вы звоните _mm_load_ps значения загружаются в регистр SIMD. Если используются все регистры, некоторые из них должны быть помещены в стек.

Процессор с SSE

8  128-bit registers labeled XMM0 - XMM7  //32-bit operating mode
16 128-bit registers labeled XMM0 - XMM15 //64-bit operating mode

Процессор с AVX / AVX2

8  256-bit registers labeled YMM0 - YMM7  //32-bit operating mode
16 256 bit registers labeled YMM0 - YMM15 //64-bt operating mode

Процессор с AVX-512 (2015/2016)

//32-bit operating mode?
32 512-bit registers labeled ZMM0 - ZMM31 //64-bit operating mode

В Википедии есть хорошее резюме по этому вопросу. AVX-512.

3

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

Точно так же, как int переменная может находиться в регистре или в памяти (или даже в обоих, в разное время), то же самое верно для переменной SSE, такой как __m128, Если имеется достаточно свободных XMM-регистров, то компилятор обычно пытается сохранить переменную в регистре (если вы не сделаете что-то бесполезное, например, получите адрес переменной), но если в реестре слишком много давления, некоторые переменные могут проливать в память.

7