【发布时间】:2012-06-22 17:36:20
【问题描述】:
我正在尝试仅使用对齐、加载和存储来矢量化 2D 模板。为此,我想基本上使用_mm_load_ps 和_mm_shuffle_ps 来获取所需的地址。
我的标量版本代码是:
void FDTD_base (float *V, float *U, int dx, int dy, float c0, float c1, float c2, float c3, float c4)
{
int i, j, k;
for (j = 4; j < dy-4; j++)
{
for (i = 4; i < dx-4; i++)
{
U[j*dx+i] = (c0 * (V[j*dx+i]) //center
+ c1 * (V[j*dx+(i-1)] + V[(j-1)*dx+i] + V[j*dx+(i+1)] + V[(j+1)*dx+i] )
+ c2 * (V[j*dx+(i-2)] + V[(j-2)*dx+i] + V[j*dx+(i+2)] + V[(j+2)*dx+i] )
+ c3 * (V[j*dx+(i-3)] + V[(j-3)*dx+i] + V[j*dx+(i+3)] + V[(j+3)*dx+i] )
+ c4 * (V[j*dx+(i-4)] + V[(j-4)*dx+i] + V[j*dx+(i+4)] + V[(j+4)*dx+i] ));
}
}
}
到目前为止,我的矢量查看代码版本:
for (j = 4; j < dy-4; j++)
{
for (i = 4; i < dx-4; i+=4)
{
__m128 b = _mm_load_ps(&V[j*dx+i]);
center = _mm_mul_ps(b,c0_i);
a = _mm_load_ps(&V[j*dx+(i-4)]);
c = _mm_load_ps(&V[j*dx+(i+4)]);
d = _mm_load_ps(&V[(j-4)*dx+i]);
e = _mm_load_ps(&V[(j+4)*dx+i]);
u_i2 = _mm_shuffle_ps(a,b,_MM_SHUFFLE(1,0,3,2));//i-2
u_i6 = _mm_shuffle_ps(b,c,_MM_SHUFFLE(1,0,3,2));//i+2
u_i1 = _mm_shuffle_ps(u_i2,b,_MM_SHUFFLE(2,1,2,1));//i-1
u_i5 = _mm_shuffle_ps(b,u_i6,_MM_SHUFFLE(2,1,2,1));//i+1
u_i3 = _mm_shuffle_ps(a,u_i2,_MM_SHUFFLE(2,1,2,1));//i-3
u_i7 = _mm_shuffle_ps(u_i6,c,_MM_SHUFFLE(2,1,2,1));//i+3
u_i4 = a; //i-4
u_i8 = c; //i+4
谁能帮我获得 j-1,j+1 .....j-4,j+4 的位置。
这不起作用:
u_j2 = _mm_shuffle_ps(d,b,_MM_SHUFFLE(1,0,3,2));//j-2 (this is incorrect)
u_j6 = _mm_shuffle_ps(b,e,_MM_SHUFFLE(1,0,3,2));//j+2
u_j1 = _mm_shuffle_ps(u_j2,b,_MM_SHUFFLE(2,1,2,1));//j-1
u_j5 = _mm_shuffle_ps(b,u_j6,_MM_SHUFFLE(2,1,2,1));//j+1
u_j3 = _mm_shuffle_ps(d,u_j2,_MM_SHUFFLE(2,1,2,1));//j-3
u_j7 = _mm_shuffle_ps(u_j6,e,_MM_SHUFFLE(2,1,2,1));//j+3
u_j4 = d; //j-4 (this is fine)
u_j8 = e; //j+4
我只需要帮助来确定如何在不使用未对齐负载的情况下获取(j-1)*dx+i、(j+1)*dx+1 .....(j-4)*dx+i 和(j+4)*dx+i。
作为一个潜在的解决方案,我想将位移3*dx 添加到存储在d 中的地址以获得(j-1)*dx+i。并将3*dx的位移减去e中存储的地址,得到(j+1)*dx+i。
同理将2*dx添加到d的地址,得到j-2,以此类推。但我不知道使用 SSE 内在函数来实施此策略。
请帮忙。我正在使用英特尔 icc 编译器。
【问题讨论】:
-
@Paul:不完全是。我正在尝试确定在涉及步幅值时如何使用
mm_shuffle_ps。上一篇文章是关于一维滑动窗口的。这是一个 2D 滑动窗口,它有一个新的维度,使它变得更加复杂。任何帮助都会非常有帮助 -
您的所有约束都牢固吗?例如,绝对没有未对齐的加载和存储?还有其他表达相同计算的方法非常有效(尤其是在 Nehalem 和更高版本的 Intel CPU 上),但确实需要未对齐的加载和存储。