使用SSE / AVX的打包双向量的部分的非时间存储

时间:2011-12-09 20:13:07

标签: caching x86 x86-64 sse avx

这是关于我previous question关于将__m256d向量的各个元素扇出到不同的内存位置(散射操作)的背驮式。我的代码将大量数据存储到内存中,而这些内容在“长时间内”不再被访问。我想通过使用非时间提示指令来减少所有这些商店生成的缓存污染量。但是,我无法想出一个很好的方法来做到这一点。以下是我的代码现在的概述:

__m256d src = ...  //  data
double *dst;
int dst_dist;

__m128d a = _mm256_extractf128_pd(src, 0);
__m128d b = _mm256_extractf128_pd(src, 1);

_mm_storel_pd(dst + 0*dst_dist, a);
_mm_storeh_pd(dst + 1*dst_dist, a);
_mm_storel_pd(dst + 2*dst_dist, b);
_mm_storeh_pd(dst + 3*dst_dist, b);

我想使用非时间提示执行64位存储,但似乎没有办法直接从XMM寄存器执行此操作。什么是实现这一目标的最佳方式?

2 个答案:

答案 0 :(得分:4)

有充分的理由避免使用具有非时间提示的部分寄存器存储。如果您尝试将许多小块数据分散到完全不相关的内存位置,则CPU的写入组合缓冲区溢出,您只需通过缓存进行通常写入(可能需要额外的性能成本)。

使用写入组合(非时间提示)的正确方法是填满整个缓存行。因此,通常将数据组合到一个完整的寄存器中,然后使用MOVNTDQ立即写入。

答案 1 :(得分:2)

您可以使用MASKMOVDQU指令存储具有非时间提示的SSE向量的部分。语义不会精确映射到您的示例,但可以使其工作。但是,此指令通常只应用于避免分支(即使这样,通常最好使用select和normal存储)。使用它也有点麻烦,因为要存储的地址隐含在指令中。

您正在执行的操作看起来很像一块矩阵转置(或90度图像旋转)。您最终是否将其他数据存储到相邻的地址?是否有某种方法可以修改算法来批量处理这些存储并编写完整的向量(甚至可能使用连续写入小的可缓存临时缓冲区并在软件中进行一些写入组合)?