簡體   English   中英

使用自動生成的C代碼對大型C ++ DLL進行性能損失

[英]Performance penalty for large C++ dll's with autogenerated C code

我正在開發一個需要調用一系列優化求解器的軟件。 每個解算器都是一個自動生成的C代碼,有數千行代碼。 我使用了200個這樣的求解器,只是要解決的優化問題的大小不同。

總而言之,這些自動生成的解算器提供了大約180MB的C代碼,我在Visual Studio 2008中使用extern "C"{ /*200 solvers' headers*/ }語法編譯為C ++。編譯全部這非常慢(使用“最大速度/ O2”優化標志,大約需要8小時)。 出於這個原因,我認為將解算器編譯成單個DLL是個好主意,然后我可以從一個單獨的軟件調用它(這將有一個合理的編譯時間,並允許我抽象出所有這些extern“ C“來自更高級別代碼的東西”。 編譯后的DLL大約是37MB。

問題是當使用DLL執行這些解算器之一時,執行需要大約30ms。 如果我只將那個單個解算器編譯成DLL,並從同一個程序調用它,那么執行速度大約快100倍(<1ms)。 為什么是這樣? 我可以繞過嗎?

DLL如下所示。 每個求解器使用相同的結構(即它們具有相同的成員變量),但它們具有不同的名稱,因此所有類型轉換。

extern "C"{
#include "../Generated/include/optim_001.h"
#include "../Generated/include/optim_002.h"
/*etc.*/
#include "../Generated/include/optim_200.h"
}

namespace InterceptionTrajectorySolver
{

__declspec(dllexport) InterceptionTrajectoryExitFlag SolveIntercept(unsigned numSteps, InputParams params, double* optimSoln, OutputInfo* infoOut)
{
  int exitFlag;

  switch(numSteps)
  {
  case   1:
    exitFlag = optim_001_solve((optim_001_params*) &params, (optim_001_output*) optimSoln, (optim_001_info*) &infoOut);
    break;
  case   2:
    exitFlag = optim_002_solve((optim_002_params*) &params, (optim_002_output*) optimSoln, (optim_002_info*) &infoOut);
    break;
  /*
    ...
    etc.
    ...
  */
  case   200:
    exitFlag = optim_200_solve((optim_200_params*) &params, (optim_200_output*) optimSoln, (optim_200_info*) &infoOut);
    break;
  }

  return exitFlag;
};

};

我不知道您的代碼是否內聯到示例中的每個案例部分。 如果你的函數是內聯函數,並且你把它全部放在一個函數中,那么它會慢很多,因為代碼是在虛擬內存中布局的,這需要在執行代碼時跳轉到CPU。 如果不是全部內聯,那么這些建議可能會有所幫助。

你的解決方案可能會被...改進

A)1)將項目划分為200個獨立的dll。 然后使用.bat文件或類似文件構建。 2)在每個名為“MyEntryPoint”的dll中創建導出函數,然后使用動態鏈接在需要時加載庫。 這將相當於一個繁忙的音樂程序,加載了很多小的DLL插件。 使用GetProcAddress獲取一個指向EntryPoint的函數指針。

要么...

B)將每個解決方案構建為單獨的.lib文件。 然后,每個解決方案將非常快速地編譯,然后您可以將它們全部鏈接在一起。 構建一個指向所有函數的函數指針數組,並通過查找來調用它。

result = SolveInterceptWhichStep;

將所有libs組合成一個大型lib不應該花費8個小時。 如果花了那么長時間,你就會做一些非常錯誤的事情。

和...

嘗試將代碼放入不同的實際.cpp文件中。 也許特定的編譯器如果它們都在不同的單元等中會做得更好......然后一旦編譯了每個單元,如果你沒有改變任何東西,它將保持編譯。

確保測量並平均多次調用優化器的時間,因為可能是在第一次調用之前設置有很大的開銷。

然后還要檢查200分支條件語句(您的開關)對您的性能做了什么! 嘗試刪除該開關進行測試,只調用測試項目中的一個解算器,但鏈接DLL中的所有解算器。 你還看到性能緩慢嗎?

我假設您生成代碼的原因是為了獲得更好的運行時性能,以及更好的正確性。 我做同樣的事情。

我建議你嘗試這種技術來找出運行時性能問題。

如果您看到100:1的性能差異,這意味着每次中斷它並查看程序的狀態,您有99%的機會看到問題所在。

就構建時間而言,確定模塊化是有意義的。 這些都不會對運行時間產生太大影響,除非它意味着你正在做瘋狂的I / O.

暫無
暫無

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

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