2017-08-30 1 views
0

Je suis nouveau dans la bibliothèque FFTW. J'ai implémenté avec succès 1D et 2D fft en utilisant la bibliothèque FFTW. J'ai converti mon code fft 2D en fft 2D multithread. Mais les résultats étaient complètement opposés. Le code 2D FFT multithread prend plus de temps à s'exécuter que le code FFT 2D sérialisé. Il me manque quelque chose quelque part. J'ai suivi toutes les instructions données dans FFTW documentation pour paralléliser le code.Augmentation du temps d'exécution lors de l'utilisation de FFTW multithread

Ceci est mon programme parallélisé 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; 
} 

Quelqu'un peut-il me s'il vous plaît aider en signalant l'erreur ce que je fais?

+0

Combien de cœurs de processeur (réels - non hyperthreading) avez-vous réellement? – twalberg

+0

@twalberg c'est quatre. –

+2

Combien de temps dure un seul thread par rapport à 4? Avez-vous essayé d'exécuter seulement 2 threads? L'accélération par rapport au nombre de threads ralentira pour trop de threads à cause des frais généraux associés au threading. – atru

Répondre

0

Ce genre de comportement est typique d'une liaison incorrecte.

D'une manière générale, les fils OpenMP devraient tous être liés à des noyaux de la même prise de courant afin d'éviter l'effet de NUMA (ce qui peut rendre suboptimale ou même pire performance).

Aussi, assurez-vous que les tâches MPI sont liées correctement (une tâche doit être lié à plusieurs noyaux des mêmes prises, et vous devez utiliser un fil de OpenMP par cœur).

En raison de MPI, il y a un risque que les threads OpenMP finissent par faire en temps partagé.

Dans un premier temps, je vous recommande de commencer à imprimer à la fois MPI et OpenMP obligatoire.

Comment arriver est fonction à la fois bibliothèque MPI et OpenMP exécution. Si vous utilisez Ouvrir MPI et compilateurs Intel, vous pouvez KMP_AFFINITY=verbose mpirun --report-bindings --tag-output ...

Ensuite, comme l'a suggéré plus tôt, je vous recommande de commencer facile et augmenter la complexité

  1. 1 MPI tâche et 1 fil OpenMP
  2. 1 tâche MPI et x threads OpenMP (x est le nombre de noyaux sur une prise de courant)
  3. x tâches MPI et 1 fil de OpenMP par tâche
  4. x tâches MPI et les fils y OpenMP par tâche

2. sera plus rapide que 1. et 4 sera plus rapide que 3.