3

这搭载了我之前关于将__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 寄存器执行此操作。实现这一目标的最佳方法是什么?

4

2 回答 2

4

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

使用写入组合(非临时提示)的正确方法是填满整个缓存行。所以通常将数据块组合成一个完整的寄存器,然后用 MOVNTDQ 一次写入。

于 2011-12-10T11:02:14.230 回答
2

MASKMOVDQU您可以使用该指令存储具有非时间提示的 SSE 向量的一部分。语义不能精确地映射到您的示例,但可以使其工作。然而,这条指令通常应该只用于避免分支(即使那样,通常最好使用选择和普通存储)。使用起来也有点麻烦,因为要存储的地址隐含在指令中。

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

于 2011-12-09T22:07:38.760 回答