我寫了一個程序,正在讀/寫數據(打開一個infile和一個outfile,讀取infile的一部分,然後處理,然後寫入outfile,並重復該循環),I/O值約爲200M/s。但是,大部分運行時間,它們都處於狀態D,這意味着等待I/O(如圖所示)1。我用dd
檢查我係統的寫入速度,即約1.8G/s。如何避免程序在狀態D
是我的程序效率低下? 或我的硬盤有問題? 我該如何處理它?
我寫了一個程序,正在讀/寫數據(打開一個infile和一個outfile,讀取infile的一部分,然後處理,然後寫入outfile,並重復該循環),I/O值約爲200M/s。但是,大部分運行時間,它們都處於狀態D,這意味着等待I/O(如圖所示)1。我用dd
檢查我係統的寫入速度,即約1.8G/s。如何避免程序在狀態D
是我的程序效率低下? 或我的硬盤有問題? 我該如何處理它?
如果使用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」。有了這些修改,我認爲你應該達到你的磁盤速度的最大值。
還要注意有一個在大多數驅動器中寫入緩存,這比磁盤讀/寫速度快,這意味着您可能會首先受到讀取速度的限制,並且在填充寫入緩存後,會受到寫入速度的限制,寫入速度通常低於讀取速度。
在對磁盤進行適當的讀寫性能測試之前,您沒有理由對磁盤的性能做任何推理。通過「正確測試」,我的意思是執行一個在互聯網上很好建立並且容易找到的可用於測試目的的基準。我當然不會得出你的程序效率低下的結論 - 它可能只是沒有足夠的I/O來達到你的磁盤的(理論上的)最大傳輸速率。或者讀取和寫入的混合可能會阻止接近最大傳輸速率。 –
您需要一種方法來獲取它正在做什麼以及它沒有做什麼的指標。 這是代碼中的調試行,或者像英特爾督察等 所以你可以有I/O定時器和計算定時器... 如果你正在寫或讀小塊,那麼它可以得到足夠的流程會減慢速度。從單個線程完成所有I/O並將其分散到各個節點上並不罕見。 您可能需要使用1或2個線程來解決小問題。我懷疑競賽狀況...或文件沒有關閉/正常沖洗。 – Holmz