簡體   English   中英

C++ 特征庫 - 二次規划,固定 vs 動態,性能

[英]C++ Eigen Library - Quadratic Programming, Fixed vs Dynamic, Performance

我正在研究做一些二次編程,並且看過不同的庫。 我見過 QuadProg++ 的各種 Eigen 變體( KDE 論壇Benjamin StephensStackOverflow 帖子)。 作為測試,我分叉了GitHub 上可用的wingit 的 Eigen 變體,以實現編譯時大小的問題,以通過模板來衡量性能。

我發現我在模板案例中的性能比來自wingsit 代碼的動態大小(MatrixXD / VectorXD)案例更差。 我知道這不是一個簡單的問題,但誰能看出為什么會這樣?

注意:我確實需要增加問題大小/迭代次數,我會盡快發布。

編輯:我在 Ubuntu 12.04 上使用 GCC 4.6.3。 這些是我正在使用的標志(從wingit的代碼修改):

CFLAGS  = -O4 -Wall -msse2 -fopenmp      # option for obj
LFLAGS  = -O4 -Wall -msse2 -fopenmp      # option for exe (-lefence ...)

靜態大小的代碼的好處通常隨着大小的增加而減少。 靜態大小代碼的典型好處主要包括(但不限於)以下幾點:

  • 基於堆棧的分配比堆分配更快。 然而,在大尺寸下,基於堆棧的分配不再可行(堆棧溢出),甚至從預取和引用局部性的角度來看是有益的。
  • 循環展開當編譯器看到一個小的靜態大小的循環時,它可以展開它,並可能使用 SSE 指令。 這不適用於較大的尺寸。

換句話說,對於小尺寸(最多可能 N=12 左右),靜態尺寸的代碼可以比等效的動態尺寸的代碼更好更快,只要編譯器對內聯和循環相當積極展開。 但是,當尺寸更大時,就沒有意義了。

此外,靜態大小的代碼也有許多缺點:

  • 沒有有效的移動語義/交換/寫時復制策略,因為這樣的代碼通常是用靜態數組實現的(為了獲得上述好處),不能簡單地交換(如交換內部指針)。
  • 較大的可執行文件,其中包含分散的函數。 假設您有一個函數模板來乘以兩個矩陣,因此,將為每個大小組合生成一個新的編譯函數(內聯或非內聯)。 然后,您有一些算法可以執行大量矩陣乘法,好吧,每個乘法都必須跳轉到(或內聯執行)該大小組合的特化。 最后,您最終需要緩存更多代碼,然后緩存未命中變得更加頻繁,這將完全破壞算法的性能。

因此,從中吸取的教訓是僅將靜態大小的向量和矩陣用於 2 到 6 維向量或矩陣等小事物。 但除此之外,最好使用動態大小的代碼(或者嘗試靜態大小的代碼,但要驗證它的性能更好,因為不能保證這樣做)。 因此,我建議您重新考慮使用靜態大小的代碼解決更大問題的想法。

暫無
暫無

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

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