_mm_set1_ps(-87);
или любой другой _mm_set
intrinsic не является допустимым статическим инициализатором с текущими компиляторами, поскольку он не обрабатывается как константное выражение .
В C ++ он компилируется во время инициализации места хранения static
(копирование из векторного литерала в другое место). И если это static __m128
внутри функции, есть защитная переменная для ее защиты.
В C он просто отказывается от компиляции, потому что C не поддерживает непостоянные инициализаторы / конструкторы. _mm_set
не похож на скобочный инициализатор для собственного собственного вектора GNU C, как показывает ответ @ benjarobin.
Это действительно глупо и, похоже, является пропущенной оптимизацией во всех 4 основных компиляторах x86 C ++ (gcc / clang / ICC / MSVC). Даже если как-то важно, чтобы у каждого static const __m128 var
был отдельный адрес, компилятор мог бы добиться этого, используя инициализированное хранилище только для чтения вместо копирования во время выполнения.
Так что кажется, что постоянное распространение не может полностью превратить _mm_set
в постоянный инициализатор, даже если оптимизация включена.
Никогда не используйте static const __m128 var = _mm_set...
даже в C ++; это неэффективно.
Внутри функции еще хуже, но глобальный охват все еще плох.
Вместо этого избегайте static
. Вы все еще можете использовать const
, чтобы остановить себя от случайного присвоения чего-то другого и сказать читателям-людям, что это константа. Без static
это не повлияет на то, где и как хранится ваша переменная. const
в автоматическом хранилище просто выполняет проверку во время компиляции, что вы не изменяете объект.
const __m128 var = _mm_set1_ps(-87); // not static
Компиляторы хороши в этом, и оптимизирует случай, когда несколько функций используют одну и ту же векторную константу, так же, как они дублируют строковые литералы и помещают их в постоянную память.
Определение констант таким образом в небольших вспомогательных функциях хорошо: компиляторы выведут постоянную настройку из цикла после включения функции.
Это также позволяет компиляторам оптимизировать все 16 байтов памяти и загружать ее с vbroadcastss xmm0, dword [mem]
или чем-то подобным.