片外memcpy?

Soa*_*Box 6 hardware cpu computer-architecture memcpy

我今天在工作中分析了一个执行大量缓冲网络活动的程序,这个程序大部分时间都花在memcpy上,只是在库管理的网络缓冲区和它自己的内部缓冲区之间来回移动数据.

这让我想到,为什么intel没有"memcpy"指令允许RAM本身(或CPU外存储器硬件)移动数据而不会触及CPU?因为每个单词必须一直带到CPU然后再次推回,当整个事情可以由内存本身异步完成时.

是否有一些架构理由认为这不实用?显然,有时副本将在物理内存和虚拟内存之间,但这些情况下,这些情况随着RAM的成本而逐渐减少.有时处理器最终会等待副本完成,因此它可以使用结果,但肯定不会总是如此.

srk*_*ing 3

这是一个大问题,包括网络堆栈效率,但我会坚持您的具体指令问题。您建议的是异步非阻塞复制指令,而不是现在使用“rep mov”可用的同步阻塞 memcpy。

一些架构和实际问题:

1) 非阻塞 memcpy 必须消耗一些物理资源,例如复制引擎,其生命周期可能与相应的操作系统进程不同。这对于操作系统来说是非常讨厌的。假设线程 A 在上下文切换到线程 B 之前启动了 memcpy。线程 B 也想要执行 memcpy,并且优先级比 A 高得多。它必须等待线程 A 的 memcpy 完成吗?如果A的memcpy有1000GB长怎么办?在核心中提供更多的复制引擎会推迟但不能解决问题。基本上,这打破了操作系统时间量和调度的传统滚动。

2) 为了像大多数指令一样通用,任何代码都可以随时发出 memcpy 指令,而不考虑其他进程已经做了或将要做什么。核心必须对任何一次运行中的异步 memcpy 操作的数量有一定的限制,因此当下一个进程出现时,它的 memcpy 可能处于任意长积压的末尾。异步副本缺乏任何确定性,开发人员只会退回到老式同步副本。

3) 缓存局部性对性能具有第一顺序的影响。L1 高速缓存中已有缓冲区的传统副本速度快得令人难以置信,并且相对节能,因为至少目标缓冲区仍保留在核心 L1 的本地。在网络复制的情况下,从内核到用户缓冲区的复制发生在将用户缓冲区交给应用程序之前。因此,该应用程序具有 L1 命中率和出色的效率。如果异步 memcpy 引擎位于核心以外的任何位置,则复制操作会将行从核心拉出(窥探),从而导致应用程序缓存未命中。网络系统效率可能会比现在差很多。

4) asynch memcpy 指令必须返回某种标记来标识副本,以便稍后用于询问副本是否完成(需要另一条指令)。给定令牌,核心将需要针对特定​​的挂起或正在进行的副本执行某种复杂的上下文查找——这些类型的操作由软件比核心微代码更好地处理。如果操作系统需要终止进程并清除所有正在进行的和挂起的 memcpy 操作怎么办?操作系统如何知道一个进程使用该指令多少次以及哪些相应的令牌属于哪个进程?

- - 编辑 - -

5) 另一个问题:核心外部的任何复制引擎都必须在原始复制性能方面与核心的缓存带宽竞争,该带宽非常高,远高于外部内存带宽。对于缓存未命中,内存子系统将同样成为同步和异步 memcpy 的瓶颈。对于至少有一些数据在缓存中的任何情况(这是一个不错的选择),核心将比外部复制引擎更快地完成复制。