2012-12-25 92 views
3

我注意到,在我編寫的任何程序中,如果我對顯示器進行大量打印(即printffprintf (stderr, "...")),執行所需的時間會明顯變慢。I/O到屏幕/標準輸出

我計算過,寫入磁盤將是緩慢的,因爲磁盤的物理限制。我不確定爲什麼在屏幕上打印會顯着減慢程序的速度。

+0

在用戶和內核空間,流水線等之間切換。 – 2012-12-25 15:46:00

+2

基本上,因爲stdio(主要)是行緩衝的,並且每個寫入都會調用系統調用。順便說一句:在虛擬終端上還有終端仿真器吃了很多週期。在多CP​​U機器上,一個CPU忙於滾動和緩衝,而另一個CPU將其輸出。 – wildplasser

回答

3

寫入終端並不是很快,而且設計也不快,因爲通常只有標準輸出纔是用戶的信息片段,他或她可以用多快的速度讀取內容。

當你寫上如終端。 linux,下面的東西發生(也許)。在每兩個連續步驟之間調用內核:

  1. 您的程序發出寫入系統調用來寫入數據。
  2. 內核恢復的終端仿真器,併產生寫入到終端設備
  3. 的終端仿真器呈現其幀的新的狀態並將其發送到X服務器
  4. X服務器操縱存儲器映射的顯示區域中的數據
  5. 內核告訴你的圖形卡交換緩衝區

而這些都是很多步驟...由於終端輸出通常只有線路緩衝,這經常發生。

+0

你能描述一下你(和這個線程中的其他人)所說的「線緩衝」嗎?還有其他種類的緩衝嗎?什麼是在終端輸出的背景下緩衝? – poundifdef

+0

@poundifdef行緩衝意味着:當您調用寫入行緩衝輸出的函數時,如果緩衝區已滿或存在換行符,則數據將存儲在緩衝區中並寫入。 – fuz

2

printf()的打印到這使得輸出慢的屏幕(終端)時,通常行緩衝。

您可以使用setvbuf()來設置stdout的緩衝區大小。

+0

所以,如果我把它設置爲打印每一個說,100行或東西,那麼它會更快? – Kitchi

+1

@Kitchi也許吧。嘗試將數據一次性輸出到文件中以獲得最佳性能。 – fuz

+0

@Kitchi很有可能。基本上緩衝輸出可以避免每行調用printf()的開銷。 –

3

取決於屏幕的類型,它的大小,圖形卡或任何輸出經過,是的,印刷的東西可以顯著時間增加了執行時間。很可能打印到磁盤實際上更快 - 磁盤每秒可能需要幾兆字節(理論上現代SATA驅動器上大約爲300-600MB/s,但實際上遲早會比這慢,因爲磁盤實際上需要將數據移動到磁盤內的盤片上 - 但它們也有大量緩存,因此寫入16MB或32MB可能需要相當長的一段時間)。嘗試添加一些時間戳到您的代碼(如果你還沒有的話),並與myprog > filemyprog > /dev/null比較myprog(或NUL:如果您在Windows),看看哪一個需要更多的時間 - 我敢打賭,它是一個將要在屏幕上 - 並寫入空設備是最快的,但只有一點點。

與印刷屏幕最大的問題是滾動 - 這意味着「洗牌everythng」,甚至與智能硬件,它可以是相當多的像素的洗牌周圍。請記住,現代顯卡更傾向於繪製3D,這與滾動2D文本屏幕的方式完全不同。

當然,除此之外,您的應用程序本身需要更多時間,因爲您調用了printf或類似的函數,這些函數並不是完全無關緊要的,所以如果您打印了很多東西,printf本身會花費一些時間 - 對於使用簡單代碼的程序,即使數據變爲「空白」,執行實際工作所需的時間也可能是10倍。