簡體   English   中英

使用OpenMP創建FFTW計划

[英]FFTW plan creation using OpenMP

我試圖並行執行幾個FFT。 我正在使用FFTW和OpenMP。 每個FFT都不同,所以我不依賴於FFTW的內置多線程(我知道使用OpenMP)。

int m;

// assume:
// int numberOfColumns = 100;
// int numberOfRows = 100;

#pragma omp parallel for default(none) private(m) shared(numberOfColumns, numberOfRows)//  num_threads(4)
    for(m = 0; m < 36; m++){

        // create pointers
        double          *inputTest;
        fftw_complex    *outputTest;
        fftw_plan       testPlan;

        // preallocate vectors for FFTW
         outputTest = (fftw_complex*)fftw_malloc(sizeof(fftw_complex)*numberOfRows*numberOfColumns);
         inputTest  = (double *)fftw_malloc(sizeof(double)*numberOfRows*numberOfColumns);

         // confirm that preallocation worked
         if (inputTest == NULL || outputTest == NULL){
             logger_.log_error("\t\t FFTW memory not allocated on m = %i", m);
         }

         // EDIT: insert data into inputTest
         inputTest = someDataSpecificToThisIteration(m); // same size for all m

        // create FFTW plan
        #pragma omp critical (make_plan)
        {
            testPlan = fftw_plan_dft_r2c_2d(numberOfRows, numberOfColumns, inputTest, outputTest, FFTW_ESTIMATE);
        }

         // confirm that plan was created correctly
         if (testPlan == NULL){
             logger_.log_error("\t\t failed to create plan on m = %i", m);
         }

        // execute plan
         fftw_execute(testPlan);

        // clean up
         fftw_free(inputTest);
         fftw_free(outputTest);
         fftw_destroy_plan(testPlan);

    }// end parallelized for loop

一切正常。 但是,如果我從計划創建周圍刪除關鍵構造(fftw_plan_dft_r2c_2d),我的代碼將失敗。 有人可以解釋原因嗎? fftw_plan_dft_r2c_2d真的不是一個“孤兒”,對嗎? 是因為兩個線程可能同時嘗試命中numberOfRowsnumberOfColumns內存位置?

幾乎所有關於線程安全的FFTW文檔都寫了:

......但必須小心謹慎,因為計划程序例程在呼叫和計划之間共享數據(例如智慧和三角表)。

結果是FFTW中唯一的線程安全(重入)例程是fftw_execute (及其新的數組變體)。 所有其他例程(例如規划器)應該一次只能從一個線程調用。 因此,例如,您可以圍繞對計划程序的任何調用包裝信號量鎖; 更簡單地說,您可以從一個線程創建所有計划。 我們認為這不應該是一個重要的限制(FFTW是針對唯一的性能敏感代碼是轉換的實際執行情況而設計的),並且計划之間共享數據的好處很大。

在FFT的典型應用中很少構建計划,因此如果必須同步它們的創建並不重要。 在您的情況下,除非數據維度發生更改,否則無需在每次迭代時創建新計划。 你寧願做以下事情:

#pragma omp parallel default(none) private(m) shared(numberOfColumns, numberOfRows)
{
   // create pointers
   double          *inputTest;
   fftw_complex    *outputTest;
   fftw_plan       testPlan;

   // preallocate vectors for FFTW
   outputTest = (fftw_complex*)fftw_malloc(sizeof(fftw_complex)*numberOfRows*numberOfColumns);
   inputTest  = (double *)fftw_malloc(sizeof(double)*numberOfRows*numberOfColumns);

   // confirm that preallocation worked
   if (inputTest == NULL || outputTest == NULL){
      logger_.log_error("\t\t FFTW memory not allocated on m = %i", m);
   }

   // create FFTW plan
   #pragma omp critical (make_plan)
   testPlan = fftw_plan_dft_r2c_2d(numberOfRows, numberOfColumns, inputTest, outputTest, FFTW_ESTIMATE);

   #pragma omp for
   for (m = 0; m < 36; m++) {
      // execute plan
      fftw_execute(testPlan);
   }

   // clean up
   fftw_free(inputTest);
   fftw_free(outputTest);
   fftw_destroy_plan(testPlan);
}

現在計划在每個線程中只創建一次,並且每次執行fftw_execute()序列化開銷都會減少。 如果在NUMA系統(例如多插槽AMD64或Intel(后)Nehalem系統)上運行,則應啟用線程綁定以實現最高性能。

暫無
暫無

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

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