Сигнал 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
это может помочь вам в этом.