簡體   English   中英

首次在Linux上執行C ++代碼的時間極慢

[英]Execution time of c++ code on Linux for the first time is extremly slow

我相信很多人都經歷過。 第一次在Linux上執行c ++代碼總是要花費更長的時間。

就像調用::clock_gettime(CLOCK_REALTIME, &ts); 第一次比我的Linux機器上的第三次慢大約五倍。

第一次分配內存比第二次慢100倍。

我嘗試了預分配並在應用程序中使用了mlockall ,但是即使如此,一個函數的第一次執行比第二個函數慢約160倍,第二個函數慢於第三個函數。

該函數的偽代碼如下。 msg在堆上分配。 但是它不包含在時間測量中。 msg2是POD,因此在slow_for_the_first_time根本沒有內存分配。

void slow_for_the_first_time(Message * msg) {
     Msg2 msg2;
     //set msg2 using msg
  .... }

只是想知道,是什么原因導致第一次執行的緩慢? 有沒有避免的方法?

erenon的答案很有幫助。 我認為可能是因為Msg2是在so庫中定義的。

在使用LD_BIND_NOW = 1之前,第一個執行時間約為8000納秒,第二個執行時間約為500納秒,第三個執行時間約為200納秒。

現在,第一個執行時間約為2000納秒,而第二個和第三個執行時間保持不變。 因此它仍然比第三次執行慢10倍,應該有其他因素影響第一次執行時間。

一些有趣的發現。

slow_for_the_first_time之前的以下調用方法可以將第一次執行時間再減少1微秒

void dummySet(Msg2& msg2)
{
    //set all fields of msg2. msg2 has about 30 fields it won't work if only set one field of msg2.
}

另一個值得一提的是,第一次執行的速度絕對與msg無關,因為下面代碼中的第二個slow_for_the_first_time

char buffer[sizeof(Message)];
memset(buffer, 0, sizeof(buffer));
slow_for_the_first_time((Message*)buffer);//calling the method with a dummy buffer.
.....
slow_for_the_first_time(msg);//calling the method for the second time with a real msg.

在下面的代碼中與第二個slow_for_the_first_time一樣快

slow_for_the_first_time(msg);//the first time takes around 2000 nanoseconds
.....
slow_for_the_first_time(msg);//the second time takes around 500 nanoseconds.

首次引用動態鏈接的符號時,需要在一組動態加載的符號中進行查找。 要查看這是否確實是問題所在,請執行以下操作:

$ LD_BIND_NOW=1 ./your_program

如果GOT和PLT中的每個條目, LD_BIND_NOW都會指示鏈接器修復地址:這將使啟動速度稍慢,但也可能解決交換中的“首次呼叫速度慢”的問題。

如果證明是問題所在,則可以嘗試靜態鏈接庫或預鏈接。

除了他們的答案中提到的惰性鏈接erenon之外,還有其他兩個因素會導致首次運行時執行緩慢:冷緩存和冷分支預測。

總體而言,后續調用的加速來自:

  • 外部符號 :鏈接器解析 完符號后,該符號將在程序的整個生命周期內有效,此后幾乎是無操作的操作;
  • 數據 :當數據由CPU處理時,它會臨時存儲在CPU緩存中 將內存加載到該緩存中是一項昂貴的操作。 但是一旦進入緩存,由於緩存確實是非常接近CPU的快速內存,因此下次可以快速使用相同的數據。 您可以閱讀有關cache的其他答案
  • CPU分支預測通過嘗試並預測代碼分支的方式來顯着改善代碼執行。 這也需要熱身。 這是關於分支預測的一個很好的答案

總體而言,代碼在首次執行時往往會變慢。 如果這是一個問題,則解決方案是:

  • LD_BIND_NOW ,在啟動時鏈接;
  • 緩存預熱;
  • 分支預測熱身。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM