C代码测量Linux中的磁盘写入时间并处理RAM缓冲
Posted
技术标签:
【中文标题】C代码测量Linux中的磁盘写入时间并处理RAM缓冲【英文标题】:C code measuring disk write time in linux and dealing with RAM buffering 【发布时间】:2016-08-12 01:48:28 【问题描述】:参考http://www.linuxatemyram.com/,它描述了磁盘 i/o 如何在内存中缓冲。我想考虑这一点,并实际撤消它,以测量将不同数量的数据写入文件所需的时间。 我要做的是根据两种情况的 i/o 了解运行时间:
-
通过
mount -t tmpfs -o size=500g tmpfs /ramdisk
作为ramdisk安装到内存中
将数据写入/scratch/
,这是一个格式化为 EXT3 或 XFS 的 900GB 希捷 sas 硬盘
我的程序在将文件写入硬盘时非常快,我确信这是因为 linux 操作系统正在缓冲 RAM 中的数据,从而使磁盘 i/o 透明......因为在我的程序完成后,如果在提示我执行rm temp_speed*
,这需要一分钟或更长时间。
例如,如果程序正在写入 10gb,则完成写入 ramdisk 需要 7 秒,完成写入 /scratch 需要 20 秒。但是我可以在写入 ramdisk 后执行 rm temp*
并在 1-3 秒内完成,而如果它是从头开始的,则删除命令需要 90 多秒才能完成。
任何人都知道我如何编写下面的程序来知道磁盘 i/o 何时在程序中完全完成?谢谢。
请注意,如果您尝试运行此代码,您可能会迅速填满您的硬盘驱动器和/或内存并导致系统崩溃。
# include <stdio.h>
# include <stdlib.h>
# include <time.h>
# define MAX_F 256
/* WARNING: running this code you risk quickly filling up */
/* your hard drive and/or memory and crashing your system. */
/* compile with -O0 no optimization */
long int get_time ( void )
long int t;
t = (long int) time( NULL );
return( t );
void diff_time ( long int *start, long int *finish )
time_t s, e;
long int diff;
long int h = 0, m = 0;
s = (time_t) *start;
e = (time_t) *finish;
diff = (long int) difftime( e, s );
h = diff / 3600;
diff -= ( h * 3600 );
m = diff / 60;
diff -= ( m * 60 );
printf(" problem runtime (h:m:s) = %02ld:%02ld:%02ld\n", h, m, diff );
printf("\n");
int main ( int argc, char *argv[] )
FILE *fp[MAX_F];
char fname[MAX_F][64];
long int a, i, amount, num_times, num_files;
long int maxfilesize;
long int start_time, end_time;
double ff[512]; /* 512 doubles = 4096 = 4k worth of data */
if ( argc != 3 )
printf("\n usage: readwrite_speed <total amount in gb> <max file size in gb>\n\n");
exit( 0 );
system( "date" );
amount = atol( argv[1] );
maxfilesize = atol( argv[2] );
if ( maxfilesize > amount )
maxfilesize = amount;
num_files = amount / maxfilesize;
if ( num_files > MAX_F )
printf("\n increase max # files abouve %d\n\n", MAX_F );
exit( 0 );
num_times = ( amount * 1024 * 1024 * 1024 ) / 4096;
num_times /= num_files;
printf("\n");
printf(" amount = %ldgb, num_times = %ld, num_files = %ld\n", amount, num_times, num_files );
printf("\n");
for ( i = 0; i < num_files; i++ )
sprintf( fname[i], "temp_speed%03d", i );
start_time = get_time();
for ( i = 0; i < num_files; i++ )
fp[i] = fopen( fname[i], "wb" );
if ( fp[i] == NULL )
printf(" can't write binary %s\n", fname[i] );
for ( i = 0; i < 512; i++ )
ff[i] = rand() / RAND_MAX;
/* 1 gb = 262,144 times writing 4096 bytes */
for ( a = 0; a < num_times; a++ )
for ( i = 0; i < num_files; i++ )
fwrite( ff, sizeof( double ), 512, fp[i] );
fflush( fp[i] );
for ( i = 0; i < num_files; i++ )
fclose( fp[i] );
end_time = get_time();
diff_time( &start_time, &end_time );
system( "date" );
【问题讨论】:
首先,不要使用fopen()
和fwrite()
。使用open()
和write()
。这样就不需要fflush()
的开销,并且可以使用O_DIRECT
绕过页面缓存。有关使用O_DIRECT
的详细信息,请参阅open.2
man page - 并注意它们。 Linux 上的 Direct IO 是一个挑剔的野兽。最后,您要测量什么?您的磁盘可以快多快地移动数据,或者它可以支持多少个单独的 IO 操作/秒?这些不是一回事,尤其是对于物理的旋转磁盘。
寻找一种简单而合理的方法来量化和显示任何人(非计算机头脑的人)在运行程序时磁盘 i/o 的影响以及该程序是否从本地 ram 或 ramdisk 访问数据,到本地硬盘,到网络共享存储,等等。并显示必须担心 1 GB 或更少的数据与 500 GB 或更多数据之间的差异以及所涉及的时间尺度。
我正在处理一些具有 256gb 和 512gb 内存的服务器,只有一个 300gb 和/或 600gb 2.5" 硬盘。linux os (SLES11.4) 非常擅长使用内存以弥补缓慢的磁盘写入,这就是阻止我获得将 N GB 写入我的旋转硬盘驱动器所需的真实经过时间的原因。
【参考方案1】:
首先,看here。 您无法 100% 保证数据在磁盘上。 您可以使用 fsync 告诉内核将数据刷新到磁盘。但是磁盘和磁盘控制器都有自己的缓存,所以即使是内核也不能总是知道它什么时候 100% 完成了。
【讨论】:
以上是关于C代码测量Linux中的磁盘写入时间并处理RAM缓冲的主要内容,如果未能解决你的问题,请参考以下文章
当运行时修改写入名称节点中的编辑日志文件时,编辑日志文件是在 RAM 还是本地磁盘上更新