У меня есть профсоюз, который выглядит так
union bareVec8f {
__m256 m256; //avx 8x float vector
float floats[8];
int ints[8];
inline bareVec8f(){
}
inline bareVec8f(__m256 vec){
this->m256 = vec;
}
inline bareVec8f &operator=(__m256 m256) {
this->m256 = m256;
return *this;
}
inline operator __m256 &() {
return m256;
}
}
__m256 должен быть выровнен по 32-байтовой границе для использования с функциями SSE и должен автоматически, даже внутри объединения.
И когда я делаю это
bareVec8f test = _mm256_set1_ps(1.0f);
Я получаю ошибку сегментации. Этот код должен работать из-за созданного мной конструктора. Тем не менее, когда я делаю это
bareVec8f test;
test.m256 = _mm256_set1_ps(8.f);
Я не получаю ошибку сегментации.
Таким образом, поскольку это работает нормально, объединение, вероятно, выровнено правильно, есть просто ошибка сегментации, вызываемая конструктором, который кажется
Я использую 64-битный компилятор Windows GCC
———————————РЕДАКТИРОВАТЬ
Мэтту удалось привести простейший пример ошибки, которая, кажется, происходит здесь.
#include <immintrin.h>
void foo(__m256 x) {}
int main()
{
__m256 r = _mm256_set1_ps(0.0f);
foo(r);
}
Я собираю с -std=c++11 -mavx
Это ошибка в g ++ для Windows. Он не выполняет 32-байтовое выравнивание стека, когда это необходимо. Ошибка 49001 Ошибка 54412
На это так нить кто-то создал скрипт Python для обработки вывода сборки с помощью g ++, чтобы решить эту проблему, так что это был бы один из вариантов.
В противном случае, чтобы избежать этого в вашем союзе, вы можете сделать функции, которые принимают __m256
вместо этого возьмите его по ссылке. У этого не должно быть никакого снижения производительности, если оптимизация не является низкой / выключена.
Если вы не знаете — псевдоним объединения вызывает неопределенное поведение в C ++, запись запрещена. m256
а затем прочитать floats
или же ints
например. Так что, возможно, есть другое решение вашей проблемы.