我已经使用mmap()和fopen(“/ dev / mem”)创建了一个映射到ARM系统中两个处理器内核之间共享的物理内存块。当运行Linux的处理器写入内存时,在其他非Linux处理器看到写入的数据之前,可能会有一秒钟的延迟。如果Linux进程在写入内存之后立即调用此系统,则长延迟消失:
system("sync; echo 3 > /proc/sys/vm/drop_caches" );
我试图直接在代码中复制该逻辑,但是长时间延迟仍然存在:
int fd;
char* data = "3";
sync();
fd = open("/proc/sys/vm/drop_caches", O_WRONLY);
write(fd, data, sizeof(char));
close(fd);
为什么sync()调用的行为与sync system命令不同?同步命令会影响虚拟内存是否会刷新sync()调用?
我知道手册说同步程序除了执行sync(2)系统调用之外什么都不做,但是我从用户空间调用sync()这一事实会影响它的行为吗?它就好像来自用户空间的同步调用仅调度同步而不是阻塞直到完成。
答案 0 :(得分:1)
你忘记了换行符。
echo 3
输出"3\n"
。
此外,您正在采用异常迂回的方式来实现共享内存,并在此过程中对其余操作系统施加巨大成本。
每次调用sync-the-command或sync-the-system-call时,都会导致操作系统刷新整个计算机上的每个文件系统;更糟糕的是,你告诉操作系统忘记它拥有的每个文件系统缓冲区,迫使操作系统重新读取磁盘上的所有内容。几乎可以通过各种方式对整个操作系统进行性能测试是非常糟糕的。
有一种更简单的方法。
使用shm_open()创建命名的共享内存区域。使用mmap访问它。仅在内存块上使用内存屏障或共享/命名的互斥锁,以确保您可以一致且安全地读取和写入它。
就复杂性而言,您当前的方法可能比普通共享内存高出1,000,000倍。
答案 1 :(得分:0)
此处drop_caches
和sync
都不合适,因为它们都处理文件系统缓存 - 这实际上并不是你在这里遇到的。 sync
似乎解决它的事实可能是巧合。 (启动sync
工具时,可能会偶然刷新数据缓存。)
您的应用程序很可能会遇到系统上两个处理器核心的缓存同步问题。尝试使用cacheflush()
系统调用来解决此问题:
#include <unistd.h>
#include <asm/unistd.h>
...
syscall(__ARM_NR_cacheflush, mapping_ptr, mapping_ptr + mapping_length, 0);
请注意,您可能需要在两个进程中刷新缓存以查看正确的结果。
对于其他映射设备,通常需要刷新对映射内存的更改,但我认为在这种情况下可能不需要。尽管如此,尝试msync()
也不会受到伤害:
msync(mapping_ptr, mapping_length, MS_SYNC); // on process writing to memory
msync(mapping_ptr, mapping_length, MS_INVALIDATE); // on process reading from memory
最后,确保使用MAP_SHARED
标记映射此内存。