16-байтовая проблема выравнивания
Я использую DirectXMath
, создавая XMMatrix
а также XMVector
в классах.
Когда я звоню XMMatrixMultiply
это бросает необработанное исключение на это.
Я обнаружил в Интернете, что это проблема с байтовым соединением, так как DirectXMath
использования SIMD
набор инструкций, который приводит к неправильному распределению кучи.
Одним из предложенных решений было использование XMFLOAT4X4
переменные, а затем изменить их на временные XMMatrix
когда это необходимо, но это не самое лучшее и быстрое решение для меня.
Еще один должен был использовать _aligned_malloc
, но я понятия не имею, как его использовать. Мне никогда не приходилось делать какие-либо выделения памяти, и для меня это черная магия.
Еще один, должен был перегрузить new operator
, но они не предоставили никакой информации, как это сделать.
А по поводу метода перегрузки я не пользуюсь new
создавать XMMatrix
объекты, так как я не использую их как указатели.
Все работало хорошо, пока я не решил разделить код на классы.
Я думаю _alligned_malloc
решение было бы лучше здесь, но я понятия не имею, как его использовать, где и когда его назвать.
2 ответа
В отличие от XMFLOAT4X4 и XMFLOAT4, которые безопасно хранить, XMMATRIX и XMVECTOR являются псевдонимами для аппаратных регистров (SSE, NEON и т. Д.). Поскольку библиотека абстрагируется от требований к типу регистра и выравниванию, вам не следует пытаться выровнять типы самостоятельно, поскольку вы можете легко создать программу, которая работает на вашем компьютере, но не работает на другом. Вам следует либо использовать безопасные типы для хранения (например, XMFLOAT4), либо открыть абстракцию и напрямую использовать векторные инструкции со специальными путями хранения и выравнивания в вашем приложении для каждого расширения вектора, которое вы пытаетесь поддерживать.
Кроме того, использование этих регистров вне контекста векторных инструкций библиотеки может вызвать неожиданные сбои по другим причинам. Например, если вы храните XMMATRIX в своей собственной структуре, некоторые архитектуры могут не создавать копии структуры.
Не претендую на полный ответ.
Есть несколько способов, которые вы не упомянули:
#define _XM_NO_INTRINSICS_
, Просто. Медленный. Работает прямо сейчас, всего одна строка кода.;)- Не хранить
XMVECTOR
а такжеXMMATRIX
на кучу. хранитьXMFLOAT4
или жеXMFLOAT4X4
и конвертировать в типы SIMD только при необходимости (чтобы они сохранялись в стеке). Помедленнее. Много кода для изменения (наверное). - Не хранить
XMVECTOR
а такжеXMMATRIX
в куче, часть 2. Просто храните ваши классы в стеке. Быстро. Довольно трудно. Много кода для изменения (наверное). - Используйте выровненный распределитель. Быстро. Жесткий. Много часов в Google, много кода для написания и отладки.
- Не используйте DirectXMath (ранее XMMath) библиотеку. Выберите любой другой (их много) или напишите свой. Быстро. Много кода для изменения (наверное).
Если вы хотите выровнять распределитель, он не имеет ничего общего с DirectX или DirectXMath. Это сложная тема. Никто не может дать вам полное решение. Но вот некоторые результаты поиска в Google:
Будьте очень внимательны. С плохим распределителем памяти вы можете поставить гораздо больше проблем, чем решить.
Надеюсь, это поможет как-то. Удачного кодирования!:)