2015-06-18 4 views
4

У меня есть союз, который выглядит, как должен быть выровнен по 32 границе байта, который будет использоваться с функциями SSE этоОбертка для __m256 производящей ошибки сегментации с конструктором

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, и должно быть автоматически, даже в пределах Союз.

И когда я делаю это

bareVec8f test = _mm256_set1_ps(1.0f); 

Я получаю ошибку сегментации. Этот код должен работать из-за созданного мной конструктора. Однако, когда я это делаю

bareVec8f test; 
test.m256 = _mm256_set1_ps(8.f); 

У меня не возникает ошибка сегментации.

Так потому, что прекрасно работает объединение, вероятно, выровнены должным образом, есть только некоторые ошибки сегментации были вызваны с помощью конструктора, кажется

Я использую GCC 64bit окна компилятор

------ --------------------------- EDIT Мэтту удалось создать простейший пример ошибки, которая, кажется, происходит здесь.

#include <immintrin.h> 

void foo(__m256 x) {} 

int main() 
{ 
    __m256 r = _mm256_set1_ps(0.0f); 
    foo(r); 
} 

Я компиляции с -std=c++11 -mavx

+0

Вы можете легко проверить гипотезу выравнивания: 'auto ptrvalue = (std :: uintptr_t) this;'. – Cameron

+1

Вы не создали экземпляр-конструктор. 'baseVec8f (__ m256 vec)' является конструктором. У экземпляра-копии есть подпись 'baseVec8f (baseVec8f &)' возможно с 'const'. 'bareVec8f test = _mm256_set1_ps (1.0f);' использует созданный компилятором конструктор копии. (хотя в этом случае он, вероятно, был бы исключен) –

+0

@MattMcNabb Я упустил 2 метода объединения, которые я включил сейчас в сообщение, является ли теперь исправление ошибки? – Thomas

ответ

5

Это ошибка в г ++ для Windows. Он не выполняет 32-байтовое выравнивание стека, когда это необходимо. Bug 49001Bug 54412


На this SO thread кто-то сделал сценарий Python для обработки результатов сборки по г ++, чтобы решить эту проблему, так что бы один вариант.

В противном случае, чтобы избежать этого в вашем союзе, вы можете сделать функции, которые принимают значение __m256 по значению, вместо этого возьмите его вместо ссылки. Это не должно иметь никакого снижения производительности, если оптимизация не будет низкой/выключена.

В случае, если вы не знаете, - объединение псевдонимов вызывает неопределенное поведение в C++, это не разрешается писать m256, а затем прочитать floats или ints, например. Поэтому, возможно, есть другое решение вашей проблемы.

+0

Да, он подтвердил, что он вызывает ошибку seg – Thomas

+1

MSVC не передает регистры SSE и AVX по значению (но GCC, ICC и CLANG do). Поэтому я всегда передаю их как ссылки на const. –