Sid*_*obe 1 c++ compiler-construction sse alignment visual-studio
我已经和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
Run Code Online (Sandbox Code Playgroud)
如果我使用Ctrl + F5运行:
object address 00345B70
_memberVariable1 address 00345B70
_sseVector address 00345B80
Run Code Online (Sandbox Code Playgroud)
如您所见,当我在调试器中运行它时,对齐方式是不同的(即不是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;
}
Run Code Online (Sandbox Code Playgroud)
非常感谢任何提示或评论.提前致谢.
在调试器下运行时,您正在使用调试堆,这可能会影响对齐.
设置_NO_DEBUG_HEAP=1在您的环境设置,看看是否有所帮助.
参见例如http://msdn.microsoft.com/en-us/library/aa366705%28v=vs.85%29.aspx
但是,使用malloc或new分配时无法保证对齐.在VS中解决这个问题的"正确"方法就是使用_aligned_malloc.
如果希望SSEVector作为另一个结构的成员,则需要更改此结构的打包(使用#pragma pack)或SSEVector的__declspec(align).
请参见如何对齐数据打包
您的情况会发生什么(除了看似巧合的调试器/非调试器差异):
SSEVector宣布未对齐.如果直接使用_aligned_malloc它,它将被对齐.TestClass也是未对齐的,并使用默认打包.如果使用它进行分配_aligned_malloc,则TestClass实例将正确对齐.这根本没有帮助,因为您希望SSEVector 成员变量对齐.
上添加一个对齐要求SSEVector使用__declspec(align)会告诉编译器SSEVector堆栈变量必须对齐,并且其SSEVector作为一个结构部件必须对齐的结构/类内.现在,如果您分配TestClass使用_aligned_malloc,它将正确对齐.SSEVector由于declspec,结构中的偏移量也正确对齐,因此SSEVector的绝对地址对您的使用是正确的.
| 归档时间: |
|
| 查看次数: |
3359 次 |
| 最近记录: |