2012-09-12 4 views
3

SSE3 명령을 사용하기 위해 기존 벡터 및 행렬 클래스를 다시 구현하려고했는데 일련의 작업을 수행 할 때마다 이러한 "메모리 액세스 위반"오류가 발생하는 것 같습니다. 벡터 배열에 대한 연산. 나는 SSE에 비교적 익숙하지 않기 때문에 간단한 시작을했습니다. 내 벡터 클래스의 전체 내용은 다음과 같습니다.SSE 작업을 사용할 때 메모리 액세스 위반이 발생했습니다.

그럼에도 불구하고 아직 많은 생성자, 접근 자 및 하나의 작업 만 수행하고 있습니다. 다음과 같이 SSE의 내 (알듯 제한) 기술을 사용하여, 나는 또한 작업을 구현 :

SSEVector3D& SSEVector3D::operator+=(const SSEVector3D& rhs) 
{ 
    __m128 * pLhs = (__m128 *) m_coords; 
    __m128 * pRhs = (__m128 *) rhs.m_coords; 

    *pLhs = _mm_add_ps(*pLhs, *pRhs); 

    return (*this); 
} 

는 이전에 나의 새로운 벡터 클래스를 속도 테스트하려면 (이 가치가 있는지 확인하기 위해 재 구현하는 모든 일을) SSEVector3D 개체의 무작위 배열을 생성하고 함께 추가하는 간단한 프로그램을 만들었습니다. 너무 복잡 아무것도 :

SSEVector3D sseSum(0, 0, 0); 

for(i=0; i<sseVectors.size(); i++) 
{ 
    sseSum += sseVectors[i]; 
} 

printf("Total: %f %f %f\n", sseSum.x(), sseSum.y(), sseSum.z()); 

sseVectors 변수는 구성 요소의 모든 -11 사이의 임의의 숫자로 초기화되는 유형 SSEVector3D의 요소를 포함하는 표준 : : 벡터입니다.

다음은 내가 겪고있는 문제입니다. sseVectors의 크기가 8,191 이하 (많은 시행 착오를 거쳐 도착한 번호)이면 정상적으로 실행됩니다.

신호 : SIGSEGV, si_code을 : 크기가 8,192 이상이면 내가 그것을 실행하려고하면,이 오류가 0 (주소에서 메모리 액세스 위반 : 0x00000080 표시)

그러나, 나는 그 print 서술문을 끝으로 주석 처리합니다. sseVectors의 크기가 8,192 이상이더라도 오류가 없습니다.

이 벡터 클래스를 작성한 방식에 문제가 있습니까? 나는, 4.6

+5

참조 : [벡터의 데이터 정렬 방법] (http://stackoverflow.com/questions/8456236/how-is-a-vectors-data) -aligned) (또한, 잘 쓰여진 첫번째 질문에 +1.) – Mysticial

+1

STL 컨테이너가 SSE와 정렬되지 않기 때문에 segfaults가 발생합니다. '8192'에서 발생하는 별난 현상은 반환 된 포인터의 정렬에 영향을주는 메모리 할당 자의 아티팩트 일뿐입니다. – Mysticial

+1

고려해야 할 중요한 질문은'_mm_add_ps()'루틴에 의해 얼마나 많은 데이터가로드되는지, 그리고 얼마나 더 비판적인지, 얼마만큼 쓰여지는지입니다. 어떻게 그 수레 배열의 실제 크기와 맞 물릴까요? 그 대답은 잘못된 계산 결과, 정렬 문제, 배열 오버런 등 적어도 세 가지 문제를 지적 할 것이라고 생각합니다. – twalberg

답변

1

먼저 GCC 버전의 우분투 12.04.1을하고 있는데, 무엇보다도, 명시 적으로 적합한 내장 함수를 통해로드 및 저장을 항상 SSE은이

__m128 * pLhs = (__m128 *) m_coords; 
__m128 * pRhs = (__m128 *) rhs.m_coords; 
*pLhs = _mm_add_ps(*pLhs, *pRhs); 

, 을하지 않는다 결코 그냥 dereferencing. 클래스에 3 개의 float 배열을 저장하는 대신 _m128 유형의 값을 저장하십시오. 이 경우 컴파일러는 align 속성을 필요로하지 않고 클래스의 인스턴스를 올바르게 정렬해야합니다.

그러나 MSVC에서는이 기능이 제대로 작동하지 않습니다. MSVC는 일반적으로 by-value 인수로 정렬 된 8 바이트보다 강력한 정렬 요구 사항을 처리 할 수없는 것으로 보입니다 .- (SSE 코드를 Windows에 이식해야 할 때 마지막으로 SSE 파트에 Intel의 C++ 컴파일러를 사용했습니다. 대신 MSVC의 ...

0

비결은 __m128 정렬 16 바이트 인 것을 알 것입니다. 당신의 float 배열을 올바르게, 당신은 가서 __m128의 배열로 플로트를 캐스팅 할 수 정렬되도록 보장하기 위해 _malloc_aligned()를 사용합니다. 확인 할당 할 수레의 수는 4로 나눌 수 있습니다.

관련 문제