2016-08-02 441 views
0

我写了一个程序,正在读/写数据(打开一个infile和一个outfile,读取infile的一部分,然后处理,然后写入outfile,并重复该循环),I/O值约为200M/s。但是,大部分运行时间,它们都处于状态D,这意味着等待I/O(如图所示)1。我用dd检查我系统的写入速度,即约1.8G/s。如何避免程序在状态D

enter image description here

是我的程序效率低下? 或我的硬盘有问题? 我该如何处理它?

+3

在对磁盘进行适当的读写性能测试之前,您没有理由对磁盘的性能做任何推理。通过“正确测试”,我的意思是执行一个在互联网上很好建立并且容易找到的可用于测试目的的基准。我当然不会得出你的程序效率低下的结论 - 它可能只是没有足够的I/O来达到你的磁盘的(理论上的)最大传输速率。或者读取和写入的混合可能会阻止接近最大传输速率。 –

+0

您需要一种方法来获取它正在做什么以及它没有做什么的指标。 这是代码中的调试行,或者像英特尔督察等 所以你可以有I/O定时器和计算定时器... 如果你正在写或读小块,那么它可以得到足够的流程会减慢速度。从单个线程完成所有I/O并将其分散到各个节点上并不罕见。 您可能需要使用1或2个线程来解决小问题。我怀疑竞赛状况...或文件没有关闭/正常冲洗。 – Holmz

回答

0

如果使用ifort,则必须明确使用缓冲的I/O。在open语句中编译或设置buffered='yes'时标记为-assume buffered_io

如果你使用的是gfortran,这是默认的,那么肯定还有其他一些问题。

编辑

我可以补充一点,这取决于你如何读取和写入数据,大部分时间可以花在解析它,即解码ASCII字符123等,并更改为2 10的基础上,直到它机器可读数据;然后在写作时做相反的事情。这样的话,如果你构建你这样的代码:

real :: vector1(10) 

do 
    read(5,*) vector1 !line has 10 values 
    write(6,*) vector1 
enddo 

如果不是这样做时,它会快得多:

character(1000) :: line1 ! use enough characters so the whole line fits 

do 
    read(5,'(A)') line1 
    write(6,'(A)') line1 
enddo 

现在你只是通过程序抽ASCII码,甚至没有知道,如果它的数字或者也许“AAAO(=)&/&%/(¤%/ & Rhgksbks --- 31”。有了这些修改,我认为你应该达到你的磁盘速度的最大值。

还要注意有一个在大多数驱动器中写入缓存,这比磁盘读/写速度快,这意味着您可能会首先受到读取速度的限制,并且在填充写入缓存后,会受到写入速度的限制,写入速度通常低于读取速度。