제목이 더 나은 이름이 없기 때문에 자신을 명확하게 설명 할 수 있을지 잘 모르겠습니다. 색인을 통해 "데이터 유형"에 액세스하는 방법을 찾고 있지만 컴파일러가 배열에 보관하도록 강제하지는 않습니다. 이 문제는 SSE/AVX 내장 함수를 기반으로 한 저수준 코드 작성시 발생합니다. vector1
및 vector2
가 정의되어 있는지임시/"주소 지정 불가능"고정 크기 배열?
inline void load(__m512 *vector, const float *in)
{
for(int i=0; i<24; i++)
vector[i] = _mm512_load_ps((in + i*SIMD_WIDTH));
}
// similarely: inline add(...) and inline store(...)
void add(float *in_out, const float *in)
{
__m512 vector1[24];
__m512 vector2[24];
load(vector1, in_out);
load(vector2, in);
add(vector1, vector2);
store(in_out, vector1);
}
사실 :
프로그래밍의 용이성을 위해 나는 "등록"(데이터 유형 __m512
)를 통해 고정 길이로, 다음과 같이 코드를 작성하는 루프를 싶습니다 배열은 컴파일러 (내 경우에는 icc
)에 문제가있는 것 같습니다 : "주소 지정 가능"하게 만들고, 스택에 보관하므로 많은 필요없는및 store
명령어를 생성합니다. 지금까지 나는 포인터 연산을 vector1
또는 vector2
으로 허용하는 것을 이해합니다.
나는 모든 것을 유지하기 위해 컴파일러에서 만 레지스터에 만 남기고 싶습니다. 이 은입니다. __m512
배열을 사용하지 않고 코드를 작성하면 개가 각각__m512
개이며 컴파일러가 더 나은 코드를 생성합니다.
솔루션 :
내가 (실패)가 (I 스위치 문 바랐다 및 다른 모든 밖으로 최적화 한 것) 다음과 같은 클래스를 사용하여 시도:
class Vector
{
inline __m512 & operator[](int i)
{
switch(i)
case 0: return component0;
// ...
case 23: return component23;
}
__m512 component0;
// ...
__m512 component23;
};
나는 또한 고려했다 매크로가 있지만 좋은 해결책을 찾을 수 없습니다.
제안 사항? 여기 아래에 대답, 내가 뭘 원하는지에 대한 자세한 예에서 코멘트 다음
감사합니다,
사이먼
(이 비록 여전히 단순화) :
inline void project(__m512 *projected_vector, __m512 *vector)
{
for(int i=0; i<3; i++)
projected_vector[i] = _mm512_add_ps(vector[i], vector[i+3]);
}
inline void matrix_multiply(__m512 *out, const float *matrix, __m512 *in)
{
for(int i=0; i<3; i++)
{
out[i] = _mm512_mul_ps( matrix[3*i+0], in[0]);
out[i] = _mm512_fmadd_ps(matrix[3*i+1], in[1], out[i]);
out[i] = _mm512_fmadd_ps(matrix[3*i+2], in[2], out[i]);
}
}
inline void reconstruct(__m512 *vector, __m512 *projected_vector)
{
for(int i=0; i<3; i++)
vector[i] = _mm512_add_ps(vector[i], projected_vector[i]);
for(int i=0; i<3; i++)
vector[i+3] = _mm512_sub_ps(vector[i], projected_vector[i]);
}
inline void hopping_term(float *in_out, const float *matrix_3x3, const float *in)
{
__m512 vector_in[6];
__m512 vector_out[6];
__m512 half_vector1[3];
__m512 half_vector2[3];
load(vector_in, in);
project(half_vector1, vector_in);
matrix_multiply(half_vector2, matrix_3x3, half_vector1);
load(vector_out, in_out);
reconstruct(vector_out, half_vector2);
store(in_out, vector_out);
}
매크로 경로를 가고 싶어하고, 모든 부두 자신을하지 않으려면, P99 유용 뭔가를 할 수 있습니다 : http://p99.gforge.inria.fr/p99-html/ – ninjalj
SSE/AVX에 대해서는 아무 것도 모르지만 프록시가있는 사용자 정의 벡터가 유용 할 것 같습니다. –
@ Mooing Duck : 더 자세히 설명해 주시겠습니까? '클래스 벡터'가 '__m512 component0 ... component23'에 대한 프록시 같은 질문에서 가능한 해결책으로 주어지지 않았습니까? 내 접근 방식은 원하는 효과를 가져 오지 않았습니다. 무엇이 변경됩니까? – Simon