[问题] 读档如何避开OS cache or buffer?

楼主: dctzeng (DC)   2014-08-12 20:25:38
我想写测试硬盘效能的程式,主要在win7 和win xp跑
希望能保证"实际"对档案做读取动作,完全关闭任何系统快取
我遇到的问题是开启档案时,如果该档先前有过读写动作时
python 中利用os.open() 或open() fd.read()时,OS并不会直接打开档案读出来
而是在 DRAM 中快取直接拿快取资料,造成发大量的读写硬盘却没有实际动作
试过这样没用
with open(copying_target_path, 'rb', buffering = 0) as fd:
避掉 FILE_SHARE_WRITE 好像也没用
高手大大救命
作者: LiloHuang (十年一刻)   2014-08-12 20:45:00
恐怕得直接用 ctypes 或者 pywin32 呼叫 CreateFileW搭配FILE_FLAG_WRITE_THROUGH, FILE_FLAG_NO_BUFFERING我刚瞧了一下 Python 2.7 的源码,并无以上的实作释出顺便附上 MSDN 重要的说明片段,http://goo.gl/pc4Dlt
作者: ckc1ark (伪物)   2014-08-12 20:52:00
作者: LiloHuang (十年一刻)   2014-08-12 20:55:00
刚刚看到有一条路可以用...应该算是隐藏的后门 XDfrom _multiprocessing import win32 之后就可以用 win32.CreateFile(...) 的 API 来设定 flag可参照 Python 官网原始码来操作 http://goo.gl/xNBXVh只不过上面两个常数没有被写进去,得查 header file 囉
楼主: dctzeng (DC)   2014-08-12 21:19:00
太感谢 呜呜 ~~可以请教一下 中文路径编码 在 win32.CreateFile 失败?
作者: LiloHuang (十年一刻)   2014-08-12 22:07:00
真尴尬,刚刚去看了一下 DLLs\_multiprocessing.pyd该档案的 Win32 PE Import Table 是写 CreateFileA猜测 CPython 2.7 当初编译时,没有用 UNICODE 来编译只能请楼主用 ctypes.windll.kernel32.CreateFileW 囉不然就只能用 win32.CreateFile(r'D:\中文字.txt', ...Non-UNICODE 版本加减用 XD 只是这样不是很好就是补充如果要自己重新编译 Python Runtime 使其支援 XD除了得选 UNICODE 模式,PyArg_ParseTuple 也得改一下但是这不是一个很正常的方式,跟官方版本一致就好
作者: os653   2014-08-13 03:24:00
参考一下#1F2nhxPv,我想应该可以直接把ANSI版改成UNICODE
楼主: dctzeng (DC)   2014-08-13 23:11:00
感谢楼上 该部会那篇是同行po的吧 XDDDD今天才搞dll来开file, 原来有更好的解法python 有内建 fd.flush 跟os.fsync 我试只对write 有效read 还是一直打中cache 我就改从做dll来解问题莫非FlushFileBuffers 跟fd.flush不同让 #1F2nhxPv 有效?
作者: LiloHuang (十年一刻)   2014-08-13 23:43:00
基本上呢该篇文章就是我第一个回应提到的,使用pywin32如果楼主愿意安装pywin32的话,那是一个很棒的选择 :D至于 fd.flush 实作原始码在这边 http://goo.gl/uirMHF根据原始码 file_flush 的实作,是使用 fflush 函式fflush 是标准 C runtime 提供的能力,而呼叫 fflush并不会呼叫 Win32 API 的 FlushFileBuffers楼主也可以用 windbg 下中断点测试 :D 应该不会hit才是毕竟 fflush 跟 FlushFileBuffers 使用的目的就不同而在这个状况的确得使用 FlushFileBuffers 再搭配我先前的推文或该文章中所提及的那两个 flag 才是正解然而 os.fsync 状况就不同了,在视窗平台上会用_commit_commit 会转呼叫 FlushFileBuffers (可下断点验证)根据以上资讯 os.fsync 应该要清缓冲,也许可以再试试当然使用时,你的 fd 本身在建立时也得具备那两个 flag
楼主: dctzeng (DC)   2014-08-14 22:42:00
楼上大大感谢 可以请教您怎么找到实作原始码?
作者: LiloHuang (十年一刻)   2014-08-14 23:05:00
关于 fd.flush 这才是对的版本 http://goo.gl/LQ6Wel上面那个连结我贴成 stackless 版,尽管内容几乎一样至于怎么样找原始码? 官网就有提供下载整包源码啦 :Dtrunk 在这 http://svn.python.org/projects/trunk/http://svn.python.org/projects/python/trunk/ 更正..要看特定版号就去官网首页抓源码,或在SVN找对应branch
楼主: dctzeng (DC)   2014-08-14 23:33:00
喔~~ 感恩 我初入门python 学习了

Links booklink

Contact Us: admin [ a t ] ucptt.com