2017-08-30 5 views
0

FFTWライブラリが新しくなりました。私はFFTWライブラリを使って1Dと2D fftを実装しました。私は2Dのfftコードをマルチスレッドの2D fftに変換しました。しかし、結果は完全に反対であった。マルチスレッドの2D FFTコードは、シリアル化された2D FFTコードよりも実行に時間がかかります。私はどこかで何かを逃している。私はFFTW documentationで与えられたすべての指示に従って、コードを並列化しました。マルチスレッドFFTW使用時の実行時間の増加

これは私の並列化2D FFT Cプログラム

#include <mpi.h> 
#include <fftw3.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <math.h> 
#include <time.h> 

#define N 2000 
#define M 2000 
#define index(i, j) (j + i*M) 

int i, j; 

void get_input(fftw_complex *in) { 
    for(i=0;i<N;i++){ 
     for(j=0;j<M;j++){ 
      in[index(i, j)][0] = sin(i + j); 
      in[index(i, j)][1] = sin(i * j); 
     } 
    } 
} 

void show_out(fftw_complex *out){ 
    for(i=0;i<N;i++){ 
     for(j=0;j<M;j++){ 
      printf("%lf %lf \n", out[index(i, j)][0], out[index(i, j)][1]); 
     } 
    } 
} 

int main(){ 
    clock_t start, end; 
    double time_taken; 
    start = clock(); 

    int a = fftw_init_threads(); 
    printf("%d\n", a); 
    fftw_complex *in, *out; 
    fftw_plan p; 

    in = (fftw_complex *)fftw_malloc(N * M * sizeof(fftw_complex)); 
    out = (fftw_complex *)fftw_malloc(N * M * sizeof(fftw_complex)); 
    get_input(in); 

    fftw_plan_with_nthreads(4); 
    p = fftw_plan_dft_2d(N, M, in, out, FFTW_FORWARD, FFTW_ESTIMATE); 

    fftw_execute(p); 

    /*p = fftw_plan_dft_1d(N, out, out, FFTW_BACKWARD, FFTW_ESTIMATE); 
    fftw_execute(p); 
    puts("In Real Domain"); 
    show_out(out);*/ 

    fftw_destroy_plan(p); 

    fftw_free(in); 
    fftw_free(out); 
    fftw_cleanup_threads(); 

    end = clock(); 
    time_taken = ((double) (end - start))/CLOCKS_PER_SEC; 
    printf("%g \n", time_taken); 

    return 0; 
} 

で誰かが私がやっている何の間違いを指摘で私を助けてくださいことはできますか?

+0

あなたは本当にハイパースレッディングのCPUコアをいくつ持っていますか? – twalberg

+0

@twalbergそれは4です。 –

+2

1回のスレッド実行時間は4時間に比べてどれくらいかかりますか? 2つのスレッドだけを実行しようとしましたか?スレッディング数とスレッド数は、スレッディングに関連するオーバーヘッドのためにスレッドが多すぎると遅くなります。 – atru

答えて

0

この種の動作は、間違ったバインディングの典型です。

一般に、OpenMPスレッドはNUMAの影響を避けるために、すべて同じソケットのコアにバインドする必要があります(パフォーマンスが最適でないか最悪になる可能性があります)。

また、MPIタスクが正しくバインドされていることを確認してください(1つのタスクは同じソケットの複数のコアにバインドされ、コアごとに1つのOpenMPスレッドを使用する必要があります)。

MPIのため、OpenMPスレッドがタイムシェアリングを行う危険性があります。

まず、MPIとOpenMPバインディングの両方の印刷を開始することをお勧めします。

これを達成する方法は、MPIライブラリとOpenMPランタイムの両方に依存します。あなたはオープンMPIおよびインテルコンパイラーを使用する場合は、以前の提案として、あなたはKMP_AFFINITY=verbose mpirun --report-bindings --tag-output ...

はその後、私はあなたが簡単に起動し、複雑さ増す

  1. 1 MPIタスクと1つのOpenMPスレッド
  2. 1つのMPIタスクとお勧めすることができますX OpenMPスレッド(Xはソケット上のコアの数である)
  3. X MPIタスクとタスクあたり1つのOpenMPスレッド
  4. X MPIタスクとタスク
あたりYのOpenMPスレッド

うまくいけば、2は1よりも速く、4は3より速くなります。

関連する問題