Я уже некоторое время работаю с SSE и вижу свою долю проблем с выравниванием. Это, однако, за пределами моего понимания:
получаю ли я другое выравнивание
запустить программу с помощью F5 (отладка) или
запускаю ли я его вне отладчика
(Ctrl + F5)!
Некоторая справочная информация:
Я использую оболочку для типа данных с поддержкой SSE - с перегруженными операторами и пользовательским распределителем (перегруженные операторы new
и delete
используют _mm_malloc
и _mm_free
). Но в приведенном ниже примере мне удалось еще больше уменьшить проблему, то есть проблема также возникает, даже если я не использую пользовательский распределитель.
Как вы можете видеть ниже, в main () я динамически размещаю объект TestClass в куче, которая содержит объект типа SSEVector. Я использую фиктивную float[2]
переменную-член для "неправильного выравнивания" стека.
Я получаю следующий вывод при запуске с F5:
object address 00346678
_memberVariable1 address 00346678
_sseVector address 00346688
И если я бегу с Ctrl + F5:
object address 00345B70
_memberVariable1 address 00345B70
_sseVector address 00345B80
Как видите, выравнивание отличается (т.е. не 16-байтовым), когда я запускаю его в отладчике. Это просто совпадение, что выравнивание является правильным при использовании Ctrl-F5? Я использую Visual Studio 2010 с новым проектом (настройки по умолчанию).
Если я объявлю объект в стеке, т.е. TestClass myObject;
, эта проблема не появится. Использование __declspec(align(16))
также не помогает.
Код, который я использовал для воспроизведения проблемы:
#include <iostream>
#include <string>
#include <xmmintrin.h> // SSE
//#include "DynAlignedAllocator.h"
//////////////////////////////////////////////////////////////
class SSEVector /*: public DynAlignedAllocator<16>*/
{
public:
SSEVector() { }
__m128 vec;
};
class TestClass
{
public:
TestClass() { }
/*__declspec(align(16))*/ float _memberVariable1 [2];
SSEVector _sseVector;
};
//////////////////////////////////////////////////////////////
int main (void)
{
TestClass* myObject = new TestClass;
std::cout << "object address " << myObject << std::endl;
std::cout << "_memberVariable1 address " << &(myObject->_memberVariable1) << std::endl;
std::cout << "_sseVector address " << &(myObject->_sseVector) << std::endl;
delete myObject;
// wait for ENTER
std::string dummy;
std::getline(std::cin, dummy);
return 0;
}
Любые подсказки или комментарии приветствуются. Заранее спасибо.