2010-02-19 78 views
13

我一直在谷歌搜索的方式来做原始(有时称为直接)i/o在mac os下。原始I/O转动操作系统页面缓存,以使应用程序更直接地访问磁盘。这很有用,因为我使用的一些文件结构在使用LRU页面替换时效率不高。实现我们需要的页面替换算法是相当直接的,但首先我们需要关闭os x默认缓冲。在打开文件时,我们已经在Linux下使用O_DIRECT标志完成了这项工作。有谁知道如何关闭在Mac OS下的页面缓冲?如何在Mac OS X上执行Raw IO? (即相当于Linux的O_DIRECT标志)

干杯 添

回答

11

在阅读完手册后,我终于找到了理想的答案。事实证明,mac os实际上与O_DIRECT具有非常相似的机制,但它不是通过fcntl的open函数。特别是有一个名为F_NOCACHE的选项,它允许您打开或关闭特定文件描述符的缓存,这正是我想要的。请参阅http://developer.apple.com/mac/library/documentation/Darwin/Reference/ManPages/man2/fcntl.2.html了解可以使用fcntl的mac版本执行的其他操作的完整运行情况,并说明其确切用途。我希望这个答案能够帮助别人。


http://lists.apple.com/archives/filesystem-dev/2007/Sep/msg00010.html是一个很好的线索,解释F_NOCACHE标志的行为方式取决于您的Mac OS版本号。


最终代码(GO):

r1, r2, err := syscall.Syscall(syscall.SYS_FCNTL, uintptr(self.file.Fd()), syscall.F_NOCACHE, 1) 
    if err != 0 { 
     fmt.Printf("Syscall to SYS_FCNTL failed\n\tr1=%v, r2=%v, err=%v\n", r1, r2, err) 
     self.Close() 
     return false 
    } 
1

您需要使用open,而不是fopen,我相信真的有你有从的/ dev/rdisk中读取原始访问?直接使用

+1

linux下使用这种方法时,你必须先安装使用“原始”命令,打开块设备为原始字符设备我知道设备。你需要在os x下玩类似的游戏吗? – 2010-02-19 21:03:00

+0

不是我能想到的。对于每个块设备,系统中有两个设备,一个是例如*的/ dev/Disk0上*和其它*的/ dev/rdisk0 * – 2010-02-19 21:05:40

+2

使用open(而不是FOPEN)避免在C库中的缓冲,但是否完全独立的形式如何操作系统的页面高速缓存来操作。如下所述,F_NOCACHE是要走的路。 – benno 2010-05-23 11:30:37

2

您可能想要使用madvise系统调用。您可以通过使用MADV_DONTNEEDMADV_WILLNEED来向内核提供有关要首先刷新哪些页面的提示。 OS X还支持mmap标志MAP_NOCACHE,它指示内核首先丢弃结果页。

+0

+1,O_DIRECT几乎没有进入Linux,因为Linus担心它不会得到适当的POSIX咨询服务来吸引任何曝光,最终发生。大多数人只是为了O_DIRECT而不是使用madvise/fadvise。使用O_DIRECT的唯一理由是在编写处理100%自己缓冲的RDBMS或类似的时候。 – 2010-02-21 04:49:56

+2

我应该注意我正在写一个DBMS。这是一个“学术”项目,即。作为高级项目的一部分。作为项目的一部分,我们正在为我们正在使用的各种文件结构推荐缓冲方案进行经验性工作,即。 B +树,ISAM,Linear Hashing,这些都是非常标准的,但我们也在实现一些更奇特的东西,比如B-Tries。作为项目的一部分,我的每个结构都有自己的建议,缓冲方案的效果最好,我的目标是一路测试这些声明。 – 2010-02-21 06:10:22