2014-10-24 3 views
5

MSVC에서 작동하는 일부 SIMD 코드를 Xcode 6에서 Clang으로 컴파일하려고합니다. 불행히도 배열 액세스 연산자가 사용자 정의 벡터 클래스에서 오버로드되어 수정할 수없는 오류가 발생합니다. 벡터 템플릿에는 SIMD 내장 함수를 사용하는 길이가 4와 8 인 배열에 대한 특수화가 있지만 벡터 요소에 대한 참조를 반환하는 배열 액세스 연산자 (해당 요소 업데이트 용)는 clang에 오류를 발생시킵니다. "비 const 참조는 사용할 수 없습니다. 벡터 요소에 바인딩 ".배열 액세스 연산자에 과부하가 걸린 경우 SIMD 벡터 요소에 액세스하는 방법은 무엇입니까?

Full source code

오버로드 운영자 :

#ifdef _MSC_VER 
    float operator[](int idx) const { return v.m256_f32[idx]; } // m256_f32 MSVC only 
    float& operator[](int idx) { return v.m256_f32[idx]; } 
#else 
    float operator[](int idx) const { return v[idx]; } 
    float& operator[](int idx) { return v[idx]; } 
#endif 

연타에서 오류 :

non-const reference cannot bind to vector element 
    float& operator[](int idx) { return v[idx]; } 
             ^~~~~~ 

답변

5

당신은 아마 이것에 대한 조합을 사용하는 것이 필요할 것 같은데요, 예 :

하고 값 연산자는 다음과 같다 :

float operator[](int idx) const { U u = { v }; return u.a[idx]; } 

참조 연산자는하지만 까다 롭습니다, 내가 볼 수있는 유일한 방법은 그것을 할이 유형의 말장난 경유 일반적인주의 사항이 너무 :

float& operator[](int idx) { return ((float *)&v)[idx]; } 

이 내용이 컴파일 될지조차 모르겠으므로 -fno-strict-aliasing이 필요할 수 있습니다.

이 불결함을 피하기 위해 회원 변수를 __m256 v;에서 U u;으로 변경하는 것이 좋습니다.

성능에 중요한 루프에서 이런 종류의 작업을하지 않기를 바랍니다.

+0

simd를 사용하는 전체적인 이유는 성능이므로 크게 느려지는 일을하고 싶지는 않습니다! – olilarkin

+0

@olilarkin : 물론 - 성능에 민감한 루프 내에서 벡터의 개별 요소에 액세스하는 경우 SIMD를 잘못 처리하고있는 것입니다. 일반적으로 이러한 유형의 작업은 성능이 좋지 않은 루프 이후에만 수행되어야합니다. 결정적인. –

+0

죄송합니다. 오해했습니다 ... 초기화에서 성능이 중요한 부분에서 개별적으로 액세스하지 않는 요소 – olilarkin

2

이것은 읽기 전용이므로 플로트에 대한 참조를 반환 할 수 없습니다. 그러나 이것은해야 런타임 값으로 작동합니다

  • > = SSE4.1 + :
  • SSE4.1 전에 _mm_extract_ps 같은 PEXTRD의 내장 함수를 사용 노조와 _mm_cvtsi128_si32 + _mm_srli_si128는 32 비트 항목에 액세스 할 (다음 경우)