2011-03-08 4 views
1

저는 잠시 동안 SSE로 작업 해 왔으며, 정렬 문제를 봤습니다. 이것은, 그러나, 내 이해를 넘어 :디버거에서 실행되는 경우 Visual Studio에서 데이터가 올바르게 정렬되지 않았습니다.

내가 할 다른 정렬 내가 디버거 (Ctrl + F5) 이외의 실행 여부를 내가 F5 (디버그) 또는 를 사용하여 프로그램을 실행 여부를!

일부 배경 정보

: 은 내가 SSE 지원 데이터 형식에 대한 래퍼를 사용하고 있습니다 - 과부하 사업자 및 사용자 정의 할당과 ( _mm_malloc_mm_free를 사용하여 newdelete 연산자를 오버로드). 그러나 아래 예에서 문제를 더욱 줄이기 위해 노력했습니다. 즉 맞춤 할당자를 사용하지 않아도 문제가 발생합니다.

아래에서 볼 수 있듯이 main()에서 동적으로 SSEVector 유형 객체가 들어있는 힙에 TestClass 객체를 할당합니다. 스택에 "missalign"하기 위해 dummy 변수 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; 
} 

어떤 힌트 또는 논평이 크게 감사하고 있습니다. 미리 감사드립니다.

+0

MS가 8192 일 수 있다고 말하는데도 '__declspec (align (numBytes)) float'에 대해 동일한 문제가 있습니다. https://msdn.microsoft.com/en-us/library /83ythb65.aspx. 어떻게 그걸 해결 했니? 디버그 모드에서만 발생합니다. – Royi

답변

5

디버거에서 실행 중일 때 디버깅 힙을 사용 중이므로 정렬에 영향을 줄 수 있습니다.

환경 설정에 _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 (정렬)을 변경해야합니다.

SSEVector가 정렬되지 않은 선언 :

는 경우에 어떻게됩니까 How align works with data packing

이 (떨어져 보이는 우연의 일치 디버거/비 디버거 차이에서)입니다 참조하십시오._aligned_malloc을 사용하여 직접 할당하면 정렬됩니다. TestClass도 정렬되지 않으며 기본 패킹을 사용합니다. _aligned_malloc을 사용하여 할당하면 TestClass 인스턴스가 올바르게 정렬됩니다. 이것은 SSEVector멤버 변수을 정렬하기를 원하기 때문에 전혀 도움이되지 않습니다.

SSEVector 스택 변수, 및 구조체의 멤버로 SSEVector는 구조체/클래스을 정렬해야한다는을 정렬되어야 컴파일러를 말할 것이다 __declspec(align)를 사용 SSEVector에 정렬 요구 사항을 추가. 자, _aligned_malloc을 사용하여 TestClass을 할당하면 올바르게 정렬됩니다. 그리고 구조체의 SSEVector 오프셋 또한 declspec으로 인해 제대로 정렬되므로 SSEVector의 절대 주소가 올바른 것으로됩니다.

+0

고마워, 방금 시도했지만 ... 불행히도, 그것은 정렬을 변경하지 않았다. 디버거에서 실행할 때 여전히 변수에 대해 8 바이트 오프셋을 얻고 있습니다. – SideLobe

+0

예, 정렬 보장이 없습니다. 확률은 단순히 우연의 일치이지만, 나는 그것을 증명할 수 없다. :). 그냥 고치고 싶다면 _aligned_malloc을 사용하십시오. – Erik

+0

_aligned_malloc 및 _mm_malloc (SSEVector 클래스의 상속에 의해) : DynAlignedAllocator <16> DynAlignedAllocator에 과부하 된 new 및 delete 연산자가 포함되어 있지만 동작을 변경하지 않습니다. – SideLobe

관련 문제