sync()调用和sync命令有何不同?

sync()调用和sync命令有何不同?,c,linux,sync,mmap,C,Linux,Sync,Mmap,我将mmap()与fopen(“/dev/mem”)一起使用,创建了到ARM系统中两个处理器内核之间共享的物理内存块的映射。当运行Linux的处理器写入内存时,在另一个非Linux处理器看到写入的数据之前,可能会有超过1秒的延迟。如果Linux进程在写入内存后立即调用此系统,则长延迟消失: system("sync; echo 3 > /proc/sys/vm/drop_caches" ); 我曾尝试在代码中直接复制该逻辑,但长时间延迟仍然存在: int fd; char* data =

我将mmap()与fopen(“/dev/mem”)一起使用,创建了到ARM系统中两个处理器内核之间共享的物理内存块的映射。当运行Linux的处理器写入内存时,在另一个非Linux处理器看到写入的数据之前,可能会有超过1秒的延迟。如果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系统命令不同?sync命令是否会影响sync()调用不影响的虚拟内存刷新


我知道手册上说sync程序只执行sync(2)系统调用,但是我从用户空间调用sync()会影响它的行为吗?它的作用就像从用户空间调用sync只是安排同步,而不是阻止同步,直到同步完成。

您忘记了换行符

echo3
输出
“3\n”

此外,在实现共享内存方面,您走的是一条非常迂回的道路,这给操作系统的其他部分带来了巨大的成本

每次调用sync命令或sync系统调用时,都会导致操作系统刷新整个计算机上的每个文件系统;更糟糕的是,您告诉操作系统忘记它拥有的所有文件系统缓冲区,迫使操作系统重新读取磁盘上的所有内容。几乎从你能想到的每一个方面来衡量整个操作系统的性能都是非常糟糕的

有一个非常非常简单的方法

使用shm_open()创建命名共享内存区域。使用mmap访问它。仅在该内存块上使用内存屏障或共享/命名互斥体,以确保您可以一致且安全地读写它


就复杂性而言,您当前的方法的成本可能是普通共享内存的1000000倍。

无论是
drop\u缓存
还是
sync
,在这里都不合适,因为这两种方法都处理文件系统缓存,而实际上您在这里遇到的并不是文件系统缓存。
sync
似乎解决了这个问题,这可能是巧合。(启动
sync
工具时,可能会意外刷新数据缓存。)

应用程序很可能在系统上的两个处理器内核之间遇到缓存同步问题。尝试使用
cacheflush()
系统调用来解决此问题:

#include <unistd.h>
#include <asm/unistd.h>
...
syscall(__ARM_NR_cacheflush, mapping_ptr, mapping_ptr + mapping_length, 0);

最后,请确保使用
MAP\u SHARED
标志映射此内存。

这感觉像是一个长期操作,但是您的
echo
将2个字节(
3
\n
)写入
drop\u缓存,而您的其他代码只写入
3
。这可能是区别吗?@WumpusQ.Wumbley
sizeof(char)==1
我尝试了两种方法,使用了一个不带尾随换行符的字符串,但没有区别。在我的示例中编码的系统echo命令会输出(隐含的)换行符。根据手册,cacheflush系统调用仅在基于MIPS的系统上可用。我有一个ARM系统,没有asm/cachectl.h源文件,所以代码片段无法编译。我还尝试了msync()、fsync()和fdatasync(),但都没有影响延迟。作为记录,我确实在内存映射上使用了MAP_共享。我还尝试将O_DIRECT添加到关联的open调用中,但我的内核在该标志上抛出了一个无效的参数错误。手动页面有点误导-
cacheflush()
也存在于ARM上,但具有不同的参数列表,并且当前未由libc包装。我已经更新了示例代码。值得一提的是,它还可以将硬件内存范围标记为不可缓存。不过,这需要比我熟悉的更大的魔力。我还有一个有待解决的问题,专门解决如何刷新使用mmap映射的内存。看这个。目前的问题更多的是试图理解为什么两种假定相同的同步方法行为不同。shm_open建议似乎不是一个在这种情况下有效的解决方案,因为第二个处理器没有运行Linux。我错了吗?说什么?您有两个处理器可以访问相同的内存,但运行两个不同的操作系统?你们有什么样的系统架构?你说的是DSP之类的子处理器吗?这是一个非对称多处理系统(AMP)。一个处理器运行Linux进行UI和一般应用程序开发。另一个处理器运行实时算法,作为支持FPGA的数据采集系统的一部分。整个系统(两个ARM内核、共享内存控制器和一个FPGA)都在Xilinx Zynq芯片中。这类信息在前期会非常有用:)。所有这些“共享记忆”的说法都是错误的。您只需要使linux处理器写入某个物理地址,并确保处理器完成该写入。这不需要涉及同步或删除VM缓冲区等。
msync(mapping_ptr, mapping_length, MS_SYNC); // on process writing to memory
msync(mapping_ptr, mapping_length, MS_INVALIDATE); // on process reading from memory