簡體   English   中英

使用 OMP 進行多個 Eigen::Matrix 初始化:分段錯誤

[英]Multiple Eigen::Matrix initializations with OMP: segmentation faults

在以下最小示例中,我嘗試在由 OMP 並行化的 for 循環中創建一些 Eigen::Matrix。 每個矩陣都包含在循環中,因此線程之間沒有數據共享或競爭條件。 當線程數等於 1 時,代碼可以完美運行,否則會出現分段錯誤。 令人難以置信的是,我得到了大小為 600x600 的矩陣的段錯誤,但不是例如 599x599 或 601x601 或 1000x1000。 任何幫助表示贊賞。 謝謝:)

#include <iostream>

#define EIGEN_DONT_ALIGN_STATICALLY
#define EIGEN_STACK_ALLOCATION_LIMIT 0
#include <Eigen/Core>

#define SIZE 600
#define THREADS 2

int main(int argc, char *argv[]) {

  // The following code always works for THREADS=1
  // When THREADS!=1, there is a seg fault if SIZE=600. 
  // There is no seg fault when THREADS!=1 and SIZE=599 or SIZE=601
  
  #pragma omp parallel for num_threads(THREADS)
  for(int n=0; n<5; ++n){
    Eigen::Matrix<double,SIZE,SIZE> mat =  Eigen::Matrix<double,SIZE,SIZE>::Zero();
  }

  return 0;
}


問題來自固定大小和有限的堆棧大小 實際上, Matrix<double,SIZE,SIZE>是在堆棧上分配的,由於SIZE相當大,它應該在大多數系統上分配 2.7 MiB,而堆棧大小通常設置為幾 MiB(在大多數 Linux 平台上默認設置為 2 MiB )。 您應該改用Dynamic矩陣大小

有關更多信息,請參閱文檔

當然,使用固定大小的限制是只有在編譯時知道大小時才有可能。 此外,對於足夠大的尺寸,例如大於(大約)32 的尺寸,使用固定尺寸的性能優勢變得可以忽略不計。 更糟糕的是,嘗試在 function 中使用固定大小創建一個非常大的矩陣可能會導致堆棧溢出,因為 Eigen 會嘗試將數組自動分配為局部變量,而這通常在堆棧上完成。

默認情況下,衍生線程的堆棧大小可能比主線程小很多。 因此,上面的代碼在生成的線程上遇到堆棧溢出。 Jérôme Richard 的替代解決方案是通過環境變量 OMP_STACKSIZE 增加衍生線程的堆棧大小。

暫無
暫無

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

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