有一个标准的、跨度版本的memcpy吗?

16

我有一个长度为10的列向量A和一个10x10的矩阵B。 B的内存存储方式是按列主序(column major)的。 我想用A向量覆盖B矩阵的第一

显然,我可以执行以下操作:

for ( int i=0; i < 10; i++ )
{
    B[0 + 10 * i] = A[i];
}

0 + 10 * i 中我故意留下了零以突出 B 使用的列主存储(零是行索引)。

在CUDA领域发生了一些有趣的事情之后,我想到是否存在执行跨步内存复制的CPU函数? 我猜在低级别上,性能取决于是否存在跨步加载/存储指令,在 x86汇编中我不记得有这样的指令?


也许你应该考虑更改这个矩阵的存储策略,或者存储它的转置。 - David Heffernan
1个回答

8

简短回答:您编写的代码已经达到了最快的速度。

长篇回答: memcpy 函数是使用一些复杂的内部函数或汇编语言编写的,因为它操作具有任意大小和对齐方式的内存操作数。如果您要覆盖矩阵的列,则操作数将具有自然对齐方式,您不需要采用相同的技巧来获得较快的速度。


我想我只是希望能够在汇编级别访问双通道和三通道内存的“非跨度”加载/存储指令。 - M. Tibbits
我不确定你所说的“非跨步”加载/存储操作是什么意思。 - Dietrich Epp
也许这只是我的错误看法,但我认为三通道内存是通过地址空间进行分段的?如果我只能写入其中一个内存芯片(以较慢的速度仅在一个通道中写入),那么这将相当于跨步memcpy?当然,这当然取决于分段的粒度。 - M. Tibbits
我不确定你所说的“跨步memcpy”是什么意思。我原以为你是指从X,X+1,X+2...复制到Y,Y+N,Y+2*N...这样做与RAM的组织方式关系不大。我建议阅读有关现代处理器工作方式的文章,特别是缓存方面的内容。 - Dietrich Epp
是的,那正是我想要的:Y、Y+N、Y+2N...你对缓存的评论让我意识到仅仅为了转置而传输到系统总线是不可行的——抱歉,我有点累了。显然,问题中的代码将留在我的Core i7的L1缓存中。 - M. Tibbits
目前还不清楚这是否属实,但是根据数组的对齐方式,可能会加快数据传输速度。一个好的memcpy应该检查对齐方式,并在具有最佳对齐方式时以不同的方式执行这些操作。你的编译器生成的代码很可能不会进行这些检查。使用memcpy的优势还有更多需要讲述。 - Mikhail

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接