Сигнал EXC_BAD_ACCESS при попытке инициализировать переменную-член класса __m128

Я использую Apple GCC 4.2.1 и наткнулся на странную проблему со следующим кодом... Я всегда получаю исключение EXC_BAD_ACCESS при попытке инициализировать переменную члена класса __m128. К сожалению, следующий упрощенный код работает в тестовом приложении, но, может быть, вы все еще можете помочь мне найти корень этой проблемы?

Я не могу понять причину исключения EXC_BAD_ACCESS - тип __m128 не является указателем, и все другие члены MyClass инициализируются и доступны без каких-либо проблем, нет признаков повреждения стека / кучи, все работает, если я использую локальные переменные и нет проблемы под MSVC... Может, что-то не так с выравниванием?

Пожалуйста помоги!

class MyClass
{
    public:
    // lots of members
    __m128 vect;

    MyClass()
    {
        vect = _mm_setr_ps (0.f, 0.f, 0.f, 10.0f); // Program received signal: “EXC_BAD_ACCESS”.
    }

    void iniialize()
    {
        __m128 localVector = _mm_setr_ps (0.f, 0.f, 0.f, 10.0f); // No problems
        vect = localVector; // Program received signal: “EXC_BAD_ACCESS”.
    }
};

3 ответа

Решение

От всего сердца: я бы сказал, проблемы с выравниванием

Особенно в той части, где написано "много членов"

смотреть на __attribute__aligned

GCC будет автоматически выравнивать __m128 правильные члены, если объект создан в стеке, но для объектов, размещенных через new Вы находитесь во власти распределителя памяти, который обычно выровнен только на 8 байт в Linux. Вам может потребоваться переопределить оператор new для вашего класса, чтобы он вызывал posix_memalign, чтобы вы всегда получали 16-байтовые выровненные объекты.

Сказав это, если вы начинаете заниматься оптимизацией кода SSE, вы можете пересмотреть то, как вы делаете кодирование - поскольку производительность обычно является стимулом для оптимизации SIMD, вы можете захотеть работать на несколько более низком уровне, чем классы C++ - как правило, вы просто хотите работать однородно с большими кусками смежных данных, то есть с 1D или 2D массивами.

Если проблема заключается в смещении стека, следует проверить -mstackrealign опция командной строки, см. документацию GCC. Это решило мои проблемы с целью MinGW. Смотрите также обсуждение по выравниванию стека. Наконец, вы можете обновить GCC до более новой версии.

С другой стороны, если вы распределяете объекты динамически, вы должны убедиться, что память выровнена, как заметил Пол. Есть такие методы, как _mm_malloc а также _mm_free это может помочь вам в этом.

Другие вопросы по тегам