Это точно так же, как когда у вас больше int
переменных, чем целочисленных регистров : компилятору, возможно, придется пролить их в память, если слишком много живых одновременно, и перезагрузить их потом. Распределение регистров для векторных регистров выполняется почти так же, как распределение регистров для целочисленных регистров, анализируя поток данных функции и выясняя, какие переменные являются живыми одновременно.
Вы должны думать о _mm_load_ps/loadu
и store/storeu
встроенных функциях как о более подробно описывающих типизацию типов в / из векторных типов, а не как о единственной вещи, которая может компилироваться в векторную инструкцию загрузки или сохранения или всегда компилироваться в загрузки / хранения.
И кстати, x86-64 имеет xmm0..15. Скомпилируйте для 64-битной системы, если вы хотите, чтобы код, которому нужны несколько регистров, был эффективен.
SSE для трехмерных векторов:
Как правило, избегайте сохранения одного вектора направления / геометрии в векторе SIMD. Вы можете эффективно добавлять, но любые перекрестные или точечные произведения или вычисления длины потребуют тасования.
Лучше, если вы можете использовать вектор со значениями 4 x
, вектор со значениями 4 y
и т. Д., Чтобы вы могли вычислить 4 длины параллельно. Смотрите https://stackoverflow.com/tags/sse/info для более подробной информации, особенно эти слайды:
SIMD на Insomniac Games (GDC 2015) , которые показывают, как выложить свои данные для эффективной SIMD. (Структура массивов, а не массив структур).
См. Также Параллельное программирование с использованием архитектуры Haswell
Иногда вы можете получить небольшую выгоду для одного вектора в тех случаях, когда вы не можете реорганизовать, чтобы вычислить множество вещей параллельно. _mm_setr_ps()
может быть медленным, если исходные данные не являются смежными.
Уже имеется несколько библиотек-оболочек C ++ для SIMD, таких как VectorClass , лицензированный Agner Fog под лицензией GPL, и некоторые другие.