【问题标题】:Is there a standard, strided version of memcpy?是否有标准的跨步版本的 memcpy?
【发布时间】:2011-08-26 04:58:01
【问题描述】:

我有一个 10 个元素长的列向量 A。我有一个矩阵 B,它是 10 乘 10。B 的内存存储主要是列。我想用列向量 A 覆盖 B 中的第一个

显然,我可以做到:

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

我在0 + 10 * i 中留下零以突出显示 B 使用列主要存储(零是行索引)。

今晚在 CUDA 领域的一些恶作剧之后,我想到可能有一个 CPU 函数来执行跨步 memcpy??我猜在低级别上,性能将取决于是否存在跨步加载/存储指令,我不记得在 x86 程序集中存在?

【问题讨论】:

  • 也许你应该考虑为这个矩阵切换存储策略,或者存储它的转置。

标签: c memcpy stride


【解决方案1】:

简短的回答:您编写的代码是最快的。

长答案:memcpy 函数是使用一些复杂的内在函数或程序集编写的,因为它对具有任意大小和对齐方式的内存操作数进行操作。如果您要覆盖矩阵的一列,那么您的操作数将自然对齐,您无需使用相同的技巧即可获得不错的速度。

【讨论】:

  • 我想我只是希望能够在汇编级访问中对双通道和三通道内存说“非”跨步加载/存储指令。
  • 我不确定您所说的“未跨步”加载/存储操作是什么意思。
  • 也许只是我的一个不正确的看法,但我认为三通道内存是通过地址空间条纹的?如果我可以只写入其中一个内存芯片(仅在一个通道中以较慢的速度写入),那将相当于一个跨步 memcpy?这当然很大程度上取决于条带化的粒度。
  • 我不再确定您所说的“跨步 memcpy”是什么意思。我以为您的意思是从 X,X+1,X+2... 复制到 Y,Y+N,Y+2*N,... 这与 RAM 的组织方式无关。我建议阅读现代处理器的工作原理,尤其是 w.r.t.缓存。
  • 是的,这正是我想要的:Y, Y+N, Y+2N, ... 你对缓存的评论让我意识到仅仅为了转置而转移到系统总线是不切实际的——抱歉,这里有点累。显然,问题中的代码将保留在我的 Core i7 上的 L1 缓存中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-07-03
  • 1970-01-01
  • 2020-03-10
  • 2017-06-29
  • 1970-01-01
  • 1970-01-01
  • 2014-12-13
相关资源
最近更新 更多