简体   繁体   English

如果在调试器中运行,则数据在Visual Studio中无法正确对齐

[英]Data not aligned correctly in Visual Studio if run in debugger

I've been working with SSE for a while now, and I've seen my share of alignment issues. 我已经在SSE上工作了一段时间,并且看到了一些对齐问题。 This, however, is beyond my understanding: 但是,这超出了我的理解:

I get different alignment whether I run the program using F5 (debug) or whether I run it outside the debugger (Ctrl+F5)! 无论是使用F5(调试)运行程序还是在调试器之外运行程序(Ctrl + F5),我都可以得到不同的对齐方式!

Some background info: I'm using a wrapper for a SSE-enabled datatype - with overloaded operators and custom allocator (overloaded new and delete operators using _mm_malloc and _mm_free ). 一些背景信息:我正在为启用SSE的数据类型使用包装器-带有重载的运算符和自定义分配器(使用_mm_malloc_mm_free重载了newdelete运算符)。 But in the example below, I've managed to reduce to problem even further, ie the issue also happens even if I don't use the custom allocator. 但是在下面的示例中,我设法进一步解决了问题,即,即使我不使用自定义分配器,该问题也会发生。

As you can see below, in main() I dynamically allocate a TestClass object on the heap, which contains a SSEVector type object. 如下所示,在main()中,我在堆上动态分配一个TestClass对象,该对象包含一个SSEVector类型的对象。 I'm using a dummy float[2] member variable to "missalign" the stack a bit. 我正在使用一个虚拟float[2]成员变量来使堆栈“未对齐”。

I obtain the following output when I run with F5: 使用F5运行时,将获得以下输出:

object address 00346678
_memberVariable1 address 00346678
_sseVector address 00346688

And if I run with Ctrl+F5: 如果我使用Ctrl + F5运行:

object address 00345B70
_memberVariable1 address 00345B70
_sseVector address 00345B80

As you can see, the alignment is different (ie not 16-byte) when I run it in the debugger. 如您所见,当我在调试器中运行对齐方式时,对齐方式是不同的(即不是16字节)。 Is it just a coincidence that the alignment is correct when using Ctrl-F5? 使用Ctrl-F5时对齐是否正确只是一个巧合? I'm using Visual Studio 2010 with a new project (default settings). 我正在将Visual Studio 2010用于新项目(默认设置)。

If I declare the object on the stack, ie TestClass myObject; 如果我在堆栈上声明对象,即TestClass myObject; , this issue does not appear. ,此问题不会出现。 Using __declspec(align(16)) does not help, either. 使用__declspec(align(16))也无济于事。

The code I used to reproduce the issue: 我用来重现该问题的代码:

#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;
}

Any hints or commentaries are greatly appreciated. 任何提示或评论都将不胜感激。 Thanks in advance. 提前致谢。

When running under the debugger, you're using the debug heap, which may affect alignment. 在调试器下运行时,您正在使用调试堆,这可能会影响对齐。

Set _NO_DEBUG_HEAP=1 in your environment settings, and see if this helps. 在您的环境设置中设置_NO_DEBUG_HEAP=1 ,看看是否有帮助。

See eg http://msdn.microsoft.com/en-us/library/aa366705%28v=vs.85%29.aspx 参见例如http://msdn.microsoft.com/en-us/library/aa366705%28v=vs.85%29.aspx

However, alignment is not guaranteed when allocating with malloc or new. 但是,使用malloc或new分配时,不能保证对齐。 The "correct" way of solving this in VS is to use _aligned_malloc . 在VS中解决此问题的“正确”方法是使用_aligned_malloc

When you want your SSEVector as a member of another structure, you need to change the packing of this structure (using #pragma pack), or the __declspec(align) of SSEVector. 当您希望SSEVector作为另一个结构的成员时,您需要更改此结构的包装 (使用#pragma pack)或SSEVector的__declspec(align)。

See How align works with data packing 请参阅对齐如何与数据打包一起使用

What happens in your cases are (apart from the seemingly coincidental debugger/non-debugger difference): 在您的情况下会发生什么(除了看似巧合的调试器/非调试器的区别):

SSEVector is declared unaligned. SSEVector被声明为未对齐。 If you allocate it directly using _aligned_malloc , it'll be aligned. 如果使用_aligned_malloc直接分配它,它将被对齐。 TestClass is also unaligned, and uses default packing. TestClass也未对齐,并使用默认包装。 If you allocate it using _aligned_malloc , the TestClass instance will be properly aligned. 如果使用_aligned_malloc分配它,则TestClass实例将正确对齐。 This doesn't help you at all, since you want the SSEVector member variable to be aligned. 这一点对您都没有帮助,因为您希望SSEVector 成员变量对齐。

Adding an alignment requirement on SSEVector using __declspec(align) will tell the compiler that SSEVector stack variables must be aligned, and that SSEVector as a struct member must be aligned within the struct/class . 使用__declspec(align)SSEVector上添加对齐要求将告诉编译器SSEVector堆栈变量必须对齐, 并且 SSEVector作为结构成员必须在struct / class中对齐。 Now, if you allocate a TestClass using _aligned_malloc , it will be properly aligned. 现在,如果使用_aligned_malloc分配TestClass ,它将被正确对齐。 And the SSEVector offset in the struct is also properly aligned due to the declspec, so the absolute address of the SSEVector will be correct for your use. 而且由于declspec,结构中的SSEVector偏移量也正确对齐,因此SSEVector的绝对地址将正确使用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM