當我們需要對某段讀寫文件并進行處理的程序進行性能測試時,文件會被系統cache住從而影響I/O的效率,必須清理cache中的對應文件的才能正確的進行性能測試。通常清理內存可以采用下面的這條命令,但這條命令只有root才能使用,另外一方面這個會清理所有的cache,也許會影響其他程序的性能。
echo 3>/proc/sys/vm/drop_caches
linux下有一個posix_fadvise函數可以用來對cache中的文件進行清理,有關posix_fadvise的詳細說明查看man手冊。
- int?posix_fadvise(int?fd,?off_t?offset,?off_t?len,?int?advice);??
”Programs? can? use? posix_fadvise? to? announce an intention to access file data in a specific pattern in the future, thus allowing the kernel to perform appropriate optimisations”
fd是文件的描述符,用于清理對應文件cache的advice值選取POSIX_FADV_DONTNEED,利用此函數編寫下面程序進行文件的清理。
- int?clear_file_cache(const?char?*filename) ??
- { ??
- ????struct?stat?st; ??
- ????if(stat(filename?,?&st)?<?0)?{ ??
- ????????fprintf(stderr?,?"stat?localfile?failed,?path:%s\n",filename); ??
- ????????return?-1; ??
- ????} ??
- ??
- ????int?fd?=?open(filename,?O_RDONLY); ??
- ????if(?fd?<?0?)?{ ??
- ????????fprintf(stderr?,?"open?localfile?failed,?path:%s\n",filename); ??
- ????????return?-1; ??
- ????} ??
- ??
- ????//clear?cache?by?posix_fadvise??
- ??
- ????if(?posix_fadvise(fd,0,st.st_size,POSIX_FADV_DONTNEED)?!=?0)?{ ??
- ????????printf("Cache?FADV_DONTNEED?failed,?%s\n",strerror(errno)); ??
- ????} ??
- ????else?{ ??
- ????????printf("Cache?FADV_DONTNEED?done\n"); ??
- ????} ??
- ??
- ????return?0; ??
- }??
此外,linux-ftools這個工具也可以幫助清理并查看文件的內存狀態,主頁上也有詳細的使用說明。編譯后我們利用fincore這個工具來查看文件在內存中的狀態,有關fincore的實現可以在linux下man mincore,mincore是根據緩存buffer指針來其指向的緩沖區判斷在cache中的狀態,fincore就是在mincore的基礎上直接操作文件,就是通過對文件mmap獲得指針,再調用mincore來判斷。
首先我們通過cp命令拷貝了一個相對有點容量的文件,然后利用fincore查看文件在內存中的cache情況,可以看到大概cache了99.55%。
接著執行上面那段代碼的運行程序,之后再執行命令查看該文件的緩存狀態
可以看到,該文件在內存中已經沒有被cache了。實際的清理效果也可以通過一些占用I/O的讀文件程序來測試,一般程序第二遍運行時候由于文件已經被cache,實際程序運行的速度會比較快,通過上面的posix_fadivse清理之后,又會恢復和第一遍差不多的時間。