2016-11-09 118 views
0

我正在編寫一個程序,需要定期循環100微秒以執行一個循環。我發現在固定的時間內定期循環。但是,如果循環時間太短,我會發現一個問題。C++準確地在「每個」100微秒內執行操作而不會暫停

下面的演示代碼(不完整的代碼)是:

  1. 增量的count每100微秒。
  2. 每1秒鐘顯示count

預期的結果是示出約10000的每一秒。

結果顯示約有四千第二

void f2(int input) 
{ 
    auto start = std::chrono::system_clock::now(); 
    auto displayStart = std::chrono::system_clock::now(); 
    while(true){ //keep looping quickly 
     auto now = std::chrono::system_clock::now(); 
     auto interval = std::chrono::duration_cast<std::chrono::microseconds>(now - start); 
     if (interval.count() > input){ //if 100 microsecond do 
      count++; 
      start = std::chrono::system_clock::now(); 
     } 

     auto displayNow = std::chrono::system_clock::now(); 
     auto displayInterval = std::chrono::duration_cast<std::chrono::microseconds>(displayNow - displayStart); 
     if (displayInterval.count() > 1000000){ //if 1 second do 
     std::cout<< "1 second count: "<<count<<std::endl; 
     count=0; 
     displayStart = std::chrono::system_clock::now(); 

     } 

    } 

} 

後,我認爲CPU調度可能是這種問題。我已經在每個循環中檢查了程序正常工作。每次迭代大約需要100微秒,這是準確的。但是,當程序/線程暫停並等待CPU重新計劃時可能會發生問題。

例如,可以放大該值以便更清晰地進行說明。線程暫停1秒。通常它會增加10000次。但是現在,對於下一次迭代,它會檢查大於100微秒,因此計數++和計數器會在1秒內復位。對於這種情況,只計數遞增1。

用下面的代碼我修改,我可以在第二完成10000 count++但問題是那些10000計數不是一秒鐘均勻分佈的。因爲這只是測試的演示程序。 我實際上想要的操作是在每100微秒精確地執行操作。但由於線程暫停,我仍然沒有找到解決這個問題的解決方案。

void f2(int input) 
{ 
    auto start = std::chrono::system_clock::now(); 
    auto displayStart = std::chrono::system_clock::now(); 
    while(true){ //keep looping quickly 
     auto now = std::chrono::system_clock::now(); 
     auto interval = std::chrono::duration_cast<std::chrono::microseconds>(now - start); 
     if (interval.count() > input){ //if 100 microsecond do 
      for(int i=0;i<interval.count()/input;i++){ //modified part 
       count++; 
      } 
      start = std::chrono::system_clock::now(); 

     } 


     auto displayNow = std::chrono::system_clock::now(); 
     auto displayInterval = std::chrono::duration_cast<std::chrono::microseconds>(displayNow - displayStart); 
     if (displayInterval.count() > 1000000){ //if 1 second do 
     std::cout<< "1 second count: "<<count<<std::endl; 
     count=0; 
     displayStart = std::chrono::system_clock::now(); 


     } 


    } 


} 

有沒有喜歡的任何方式: 如。使過程不停頓。保持它在CPU(不太可能) 使演示程序中的計數動作每100微秒工作?

非常感謝您

+12

對於這種精度,您需要[實時操作系統](https://en.wikipedia.org/wiki/Real-time_operating_system)。通用的操作系統不會讓你實現這一點 - 你的程序可能會隨時被驅動程序中斷,比如說。無論如何 - 你想解決什麼樣的問題,你覺得,需要性能達到10,000 FPS? –

+0

謝謝你的回答。我必須使用Linux作爲程序。我正在編寫一個軟件開關,用於計算某些數據用於其他目的的計數器每100微秒需要* 0.08。 (計算每個端口的擁塞數據) –

+0

恐怕,您必須找到另一種計算該數據的方式。如果你解釋了你試圖解決的實際問題,而不是你嘗試的解決方案(你無法繼續工作),你可能會得到一些幫助。另請參閱:[XY問題](http://xyproblem.info/) –

回答

0

有N個桶,其中N是足夠大,使得調度延遲將不會是一個問題。

跟蹤上次運行衰減代碼的時間。

當一個新的數據包「走出去」,把它的基礎上最後一次您的衰變碼跑桶(若小於100毫秒,鬥0,如果200毫秒,1桶等)。

當您的衰變代碼運行時,在正確衰減所有內容並更新時間戳後計算當前值。

請注意,爭用(線程更新和線程衰減)仍然是一個問題。你可以在一定程度上通過對計數器,原子標誌和指針以及非性能敏感代碼(比如說衰變代碼)中的繁忙循環進行雙重或三重緩衝來解決這個問題。

或者,不是記錄計數,而是記錄時間戳。消耗時間戳的緩衝區,在那個時刻衰減。涉及緩衝區大小和多線程的類似問題依然存在,並有類似的解決方案

或者,在執行計數的代碼中執行衰減數學運算。