![关于共享内存行为](https://linux22.com/image/18088/%E5%85%B3%E4%BA%8E%E5%85%B1%E4%BA%AB%E5%86%85%E5%AD%98%E8%A1%8C%E4%B8%BA.png)
在使用文件支持的共享内存时注意到奇怪的性能行为(即打开用户定义的文件和 mmap() 到进程空间中)。在对共享内存部分执行 memcpy() 时,有时会观察到毫秒级的延迟。具体来说,正常情况下 0.4us 即可复制 2048 个字节,但有时相同数量的字节复制需要约 10 - 20 毫秒。这种情况随时都会随机发生。接下来的2048帧数据又回到正常时间。
内核版本为2.6.27.23-0.1-preempt。
感谢任何人提供的有关正在发生的事情以及延迟原因的任何线索。我什至尝试过使用 shm_open() 然后使用 mmap(),没有区别
调用mmap
看起来像这样:
int fd = ::open("somefile", flags, 0666);
if(fd != -1) {
myBasePointer = ::mmap(0, sizeInBytes,
PROT_READ|PROT_WRITE, MAP_SHARED,
fd, offsetInBytes);
}
一个进程创建文件并mmap
保存,其他进程打开文件并将mmap
其放入其地址空间。该文件是普通文件系统上的普通文件。
答案1
想法 1:尝试在 mmap 调用中添加 MAP_LOCKED,以确保页面始终由真实 RAM 支持。即使您有大量 RAM,您需要的部分仍然可能由于某种原因被调出页面。由于您似乎对延迟敏感,因此无论当前硬件上的可用 RAM 量如何,都建议指定此标志。
想法 2:同时指定 MAP_POPULATE 以确保页表条目是在 mmap 时而不是在故障时创建的。尽管据我所知,这只会在第一个页面错误时导致延迟,而不会在后续页面错误时导致延迟。但这又是一次很好的防守练习。
想法 3:使用匿名共享映射(而不是由真实文件支持)从而消除文件系统是否会导致延迟消失?如果这有帮助,您始终可以从辅助线程将匿名共享区域的内容写入文件(可能以较低的频率)。
想法 4:简单地尝试使用更新的内核。自从你提出问题以来,Linux 内核已经发生了很大的变化。
最后,您如何测量 memcpy 延迟?您是否有信心您不是:
- 包括由于获取当前时间而导致的一些大延迟?例如,如果您正在调用系统调用,则系统调用延迟;也不
- 包括NTP校正引起的时钟跳跃;也不
- 包括锁定延迟(2k 的 memcpy 不是原子的);也不
- 使用精度超过准确度的时间测量方法?