【问题标题】:Memory to Memory transfer optimization, How not to memcpy?内存到内存的传输优化,怎么不用memcpy?
【发布时间】:2013-07-30 07:17:29
【问题描述】:

我已经看到类似问题的其他答案,“快速 memcpy”,以及其他人的建议,“找出一种复制的方法”......我有一个有点像这样的程序现在我正在尝试优化...它有多个线程在 1024 字节块上执行 memcpy,还使用 ​​agner fog 的 asmlib 来压缩性能,但受到内存速度的限制。

您能否举例说明在某些情况下如何复制它可以比memcpy 更快?

【问题讨论】:

  • 好吧,你为什么需要复制它?它从何而来,又将走向何方?
  • /* memcpy(dest, source, size); */
  • 这显然取决于您在做什么,特别是您要复制的内容和原因,所以请更加具体。也就是说,在最近的机器上,我希望 1 KiB 的副本几乎与读取 1 KiB 的速度一样快(写入每个字只需要几个周期的缓存,而回写负责主内存当您不注意时 - 因此延迟不是问题,带宽也足够)。
  • 如果您有指向原始内存的指针,您可以避免复制。当然,那时你不能随意修改。
  • 这看起来有点像XY problem,你有一个你想使用的解决方案,你问我们如何使用它,但你没有告诉我们你为什么要使用那个解决方案或导致您选择解决方案的实际问题。甚至可能有更好的解决方案,但我们无法告诉您,因为我们不知道您为什么要这样做。

标签: c performance memory optimization memcpy


【解决方案1】:

如果您有进程在多处理器环境中处理内存,您可以检查 NUMA 架构。

我不知道 NUMA 是否会影响胎面。如果不是,我可以建议您检查您正在使用的 cpu 架构是如何工作的。

【讨论】:

    【解决方案2】:

    没有看到任何代码,这很难明确回答。听起来您正在将两个 512 字节数据扇区读入一个 1024 字节缓冲区,但您希望在数据末尾附加额外的 64 个字节。

    分配一个 1088 字节的缓冲区,将您的读取定向到缓冲区的偏移量 0 和偏移量 512,然后使用从偏移量 1024 开始的 64 字节数据更新缓冲区。

    如果您希望另一个线程在没有 memcpy 的情况下拥有此数据,则将指针传递给 1088 缓冲区的开头。

    希望这与您的应用程序正在做的事情很接近。

    【讨论】:

    • 感谢您的回复,是的,这就是我正在做的,但问题是,多个线程正在访问 1024 字节块,但每个线程都将各自的 64 字节数据附加到末尾1024 字节块,因为同步不是一个选项,我现在的问题是交换指向 1024 字节块的指针,而不破坏每个线程附加的数据(64 字节),我现在正在做的是将整个 1024 块传输到预为每个线程分配私有缓冲区,然后从那里更改 64 字节......因此没有冲突......
    • “因为同步不是一个选项” - 为什么同步不是一个选项?我的意思是,没有很多选择。要么同步写入,要么像现在做的那样做一些事情,给每个线程一个副本来处理并在最后合并它们。
    • @FlorentinoTuason,你可以做的是为每个线程分配一个唯一的 64 字节块,并让它们在运行时填充它。然后你可能想要一个字节数组,每个线程一个字节,这样当线程填充了它的 64 个字节时,它会将字节设置为 1。当数组中的所有字节都有 1 时,所有插槽都有被填满。因此,通过大规模并行存储“箱”来避免同步。
    • @Ed S,我用同步编码它,比我现在使用的慢得多,我也希望线程数增加,使用同步只会严重损害性能,而它在这里使用同步绝对是有意义的,我真的想避免它......
    • @FlorentinoTuason,这是特定于应用程序的。但是,如果您要开发一个“工作队列”,然后让一个从队列中删除项目的线程更新缓冲区,然后获取下一个项目,该怎么办。如果您有一个多处理器内核并且只使用与处理器一样多的线程,那么并行工作线程最有意义。
    猜你喜欢
    • 2015-05-29
    • 2016-04-25
    • 1970-01-01
    • 2010-11-15
    • 2014-05-05
    • 2015-10-02
    • 2010-09-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多