标题取得不够好,而且我不确定我是否已经清楚地表达了自己。我正在寻找一种通过索引访问“数据类型”的方法,但不强制编译器将其保留在数组中。该问题出现在基于SSE/AVX内部函数的低级代码编写中。为了方便编程,我想编写以下代码,使用“寄存器”(数据类型
__m512
)上的固定长度循环: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);
}
< p >由于< code >vector1和vector2
被定义为数组,这似乎对编译器(icc
在我的情况下)有些麻烦:它似乎被迫使它"可寻址",将其保留在堆栈上,从而生成了许多我不需要的load
和store
指令。据我所知,这是为了允许使用vector1
或vector2
进行指针算术运算。
我希望编译器将所有内容都保留在寄存器中。我知道这是可能的:如果我写的代码没有使用__m512
数组,而是使用许多单独的__m512
变量,编译器会生成更好的代码。
解决方案:
我尝试使用以下类(但没有成功):(我希望switch语句和其他所有内容都会被优化掉):
class Vector
{
inline __m512 & operator[](int i)
{
switch(i)
case 0: return component0;
// ...
case 23: return component23;
}
__m512 component0;
// ...
__m512 component23;
};
我也考虑过宏,但找不到好的解决方案。
有什么建议吗?
谢谢,
Simon
以下是在下方回答中的评论,这是一个更详细的示例(虽然仍然简化):
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);
}
class Vector
不是类似于__m512 component0 ... component23
的代理吗?我的方法没有带来期望的效果,你会改变什么吗? - Simon