如果正确地在调试器中运行的数据没有对齐在Visual Studio正确地、器中、数据、Studio

由网友(幼稚园叫兽)分享简介:我一直与上交所有一段时间了,我已经看到我的那份对齐问题。然而,这已经超出了我的理解:我得到不同的排列是否我运行使用F5键(调试)或程序我是否运行在调试器外部(按Ctrl + F5)!一些背景信息:我使用的包装器SSE功能的数据类型 - 用重载运算符和自定义分配器(重载新和删除使用 _mm_malloc运营商和 _mm...

我一直与上交所有一段时间了,我已经看到我的那份对齐问题。然而,这已经超出了我的理解:

  

我得到不同的排列是否我   运行使用F5键(调试)或程序   我是否运行在调试器外部   (按Ctrl + F5)!

一些背景信息: 我使用的包装器SSE功能的数据类型 - 用重载运算符和自定义分配器(重载删除使用 _mm_malloc运营商 _mm_free )。但是,在下面的例子中,我已经成功地减少问题,甚至进一步,即问题也会发生,即使我不使用自定义的分配器。

正如你可以看到下面,在main()动态地分配在堆上,其中包含一个SSEVector类型的对象TestClass的对象。我使用的是虚拟浮法[2] 成员变量missalign叠了一下。

我得到下面的输出,当我与F5运行:

 对象地址00346678
_memberVariable1地址00346678
_sseVector地址00346688
 

如果我用Ctrl + F5运行:

 对象地址00345B70
_memberVariable1地址00345B70
_sseVector地址00345B80
 

正如你所看到的,对齐方式是不同的(即不是16个字节),当我在调试器中运行。难道只是一个巧合,使用Ctrl-F5当对准是正确的?我使用Visual Studio 2010中有一个新的项目(默认设置)。

10个Visual Studio原生开发调试技巧

如果我宣布了对象中的堆栈,即在的TestClass myObject的; ,这个问题不会出现。使用 __ declspec(对齐(16))并没有帮助,无论是。

在code我来重现问题:

 的#include<的iostream>
#包括<字符串>
#包括< xmmintrin.h> // SSE
//#包括DynAlignedAllocator.h

////////////////////////////////////////////////// ////////////
类SSEVector / *:公共DynAlignedAllocator< 16> * /
{
上市:
    SSEVector(){}

    __m128 VEC;
};

类识别TestClass
{
上市:
    识别TestClass(){}

    / * __ declspec(对齐(16))* /浮_memberVariable1 [2];
    SSEVector _sseVector;
};

////////////////////////////////////////////////// ////////////
INT主要(无效)
{
    TestClass的* myObject的=新TestClass的;

    性病::法院<< 目标地址<< myObject的<<的std :: ENDL;
    性病::法院<< _memberVariable1地址<<及(myObject-> _memberVariable1)<<的std :: ENDL;
    性病::法院<< _sseVector地址<<及(myObject-> _sseVector)<<的std :: ENDL;

    删除myObject的;

    //等待ENTER
    标准::字符串哑;
    的std ::函数getline(给std :: cin,假);

    返回0;
}
 

任何提示或评论都大大AP preciated。先谢谢了。

解决方案

在调试器下运行,您使用的调试堆,这可能会影响对齐。

设置 _NO_DEBUG_HEAP = 1 在您的环境设置,并查看是否这会有所帮助。

请参阅例如 http://msdn.microsoft.com/en -us /库/ aa366705%28V = vs.85%29.aspx

然而,对齐不使用malloc或新分配时保证。在VS解决这个的正确的方法是使用 _aligned_malloc

当你想你的SSEVector为另一种结构中的一员,你需要(使用#pragma包)来改变这种结构的包装的,或者__declspec(调整)SSEVector的。

请参阅如何与数据打包

在你的情况下,会发生什么情况是(除了看似巧合的调试器/非调试器的区别):

SSEVector 声明对齐。如果分配直接使用 _aligned_malloc ,它会保持一致。 的TestClass 也对齐,并使用默认的包装。如果它分配使用 _aligned_malloc 的TestClass 实例将被正确对齐。这并不能帮助你在所有的,因为你想要的 SSEVector 的成员变量的对齐。

添加使用的 SSEVector 对齐要求 __ declspec(调整)将告诉 SSEVector 堆栈变量必须对齐,和的是 SSEVector 作为结构成员必须对齐的结构/班的。现在,如果你分配一个的TestClass 使用 _aligned_malloc ,它会被正确对齐。而 SSEVector 在结构中的偏移也适当地因declspec对齐,所以SSEVector的绝对地址将是正确的为您的使用。

I've been working with SSE for a while now, and I've seen my share of alignment issues. 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)!

Some background info: I'm using a wrapper for a SSE-enabled datatype - with overloaded operators and custom allocator (overloadednew and delete operators using _mm_malloc and _mm_free). But in the example below, I've managed to reduce to problem even further, i.e. 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. I'm using a dummy float[2] member variable to "missalign" the stack a bit.

I obtain the following output when I run with F5:

object address 00346678
_memberVariable1 address 00346678
_sseVector address 00346688

And if I run with Ctrl+F5:

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

As you can see, the alignment is different (i.e. not 16-byte) when I run it in the debugger. Is it just a coincidence that the alignment is correct when using Ctrl-F5? I'm using Visual Studio 2010 with a new project (default settings).

If I declare the object on the stack, i.e. TestClass myObject;, this issue does not appear. Using __declspec(align(16)) does not help, either.

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.

See e.g. http://msdn.microsoft.com/en-us/library/aa366705%28v=vs.85%29.aspx

However, alignment is not guaranteed when allocating with malloc or new. The "correct" way of solving this in VS is to use _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.

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. If you allocate it directly using _aligned_malloc, it'll be aligned. TestClass is also unaligned, and uses default packing. If you allocate it using _aligned_malloc, the TestClass instance will be properly aligned. This doesn't help you at all, since you want the SSEVector member variable to be aligned.

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. Now, if you allocate a TestClass using _aligned_malloc, it will be properly aligned. 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.

阅读全文

相关推荐

最新文章