2010-12-22 4 views
3

Ich versuche, einen Openmp-Code von here zu verstehen. Sie können den folgenden Code sehen.Niedrige Leistung in einem OpenMP-Programm

  1. Um die Beschleunigung, Differenz zwischen der seriellen und omp Version zu messen, benutze ich time.h, haben Sie Recht, diesen Ansatz zu finden?

  2. Das Programm läuft auf einem 4-Kern-Rechner. Ich gebe export OMP_NUM_THREADS="4" an, kann aber nicht wesentlich beschleunigen, normalerweise bekomme ich 1,2 - 1,7. Welche Probleme sehe ich in dieser Parallelisierung?

  3. Welches Debug/Performance-Tool könnte ich verwenden, um den Leistungsverlust zu sehen?

Code (für die Kompilierung Ich benutze xlc_r -qsmp=omp omp_workshare1.c -o omp_workshare1.exe)

#include <omp.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <sys/time.h> 
#define CHUNKSIZE 1000000 
#define N  100000000 

int main (int argc, char *argv[]) 
{ 
    int nthreads, tid, i, chunk; 
    float a[N], b[N], c[N]; 
    unsigned long elapsed; 
    unsigned long elapsed_serial; 
    unsigned long elapsed_omp; 
    struct timeval start; 
    struct timeval stop; 


    chunk = CHUNKSIZE; 

    // ================= SERIAL  start ======================= 
    /* Some initializations */ 
    for (i=0; i < N; i++) 
     a[i] = b[i] = i * 1.0; 
    gettimeofday(&start,NULL); 
    for (i=0; i<N; i++) 
    { 
     c[i] = a[i] + b[i]; 
     //printf("Thread %d: c[%d]= %f\n",tid,i,c[i]); 
    } 
    gettimeofday(&stop,NULL); 
    elapsed = 1000000 * (stop.tv_sec - start.tv_sec); 
    elapsed += stop.tv_usec - start.tv_usec; 
    elapsed_serial = elapsed ; 
    printf (" \n Time SEQ= %lu microsecs\n", elapsed_serial); 
    // ================= SERIAL  end ======================= 


    // ================= OMP start ======================= 
    /* Some initializations */ 
    for (i=0; i < N; i++) 
     a[i] = b[i] = i * 1.0; 
    gettimeofday(&start,NULL); 
#pragma omp parallel shared(a,b,c,nthreads,chunk) private(i,tid) 
    { 
     tid = omp_get_thread_num(); 
     if (tid == 0) 
     { 
      nthreads = omp_get_num_threads(); 
      printf("Number of threads = %d\n", nthreads); 
     } 
     //printf("Thread %d starting...\n",tid); 

#pragma omp for schedule(static,chunk) 
     for (i=0; i<N; i++) 
     { 
      c[i] = a[i] + b[i]; 
      //printf("Thread %d: c[%d]= %f\n",tid,i,c[i]); 
     } 

    } /* end of parallel section */ 
    gettimeofday(&stop,NULL); 
    elapsed = 1000000 * (stop.tv_sec - start.tv_sec); 
    elapsed += stop.tv_usec - start.tv_usec; 
    elapsed_omp = elapsed ; 
    printf (" \n Time OMP= %lu microsecs\n", elapsed_omp); 
    // ================= OMP end ======================= 
    printf (" \n speedup= %f \n\n", ((float) elapsed_serial)/((float) elapsed_omp)) ; 

} 
+0

Sie können auch angeben, welches Betriebssystem und welcher Compiler anderen helfen soll, # 1 und # 3 zu beantworten. –

Antwort

1

Es gibt nichts wirklich falsch mit dem Code wie oben, aber Ihre Speedup wird begrenzt durch die Tatsache, dass die Hauptschleife, c = a + b, hat sehr wenig Arbeit - die Zeit für die Berechnung (eine einzige Addition) wird von Speicherzugriffszeit (2 Ladevorgänge und ein Speicher) dominiert, und es gibt mehr Konkurrenz für die Speicherbandbreite mit mehr Threads auf dem Array.

Wir können dies testen, indem die Arbeit innerhalb der Schleife machen mehr rechenintensive:

c[i] = exp(sin(a[i])) + exp(cos(b[i])); 

Und dann bekommen wir

$ ./apb 

Time SEQ= 17678571 microsecs 
Number of threads = 4 

Time OMP= 4703485 microsecs 

speedup= 3.758611 

, die offensichtlich auf die 4x viel näher ist ein Speedup würde erwarten von.

Update: Oh, und zu den anderen Fragen - gettimeofday() ist wahrscheinlich gut für das Timing, und auf einem System, wo Sie xlc verwenden - ist das AIX? In diesem Fall ist peekperf ein gutes Gesamtperformance-Tool, und die Hardware-Leistungsmonitore geben Ihnen Zugriff auf Speicherzugriffszeiten. Auf x86-Plattformen bieten kostenlose Tools zur Leistungsüberwachung von Threaded-Code cachegrind/valgrind für das Debugging der Cache-Leistung (hier nicht das Problem), scalasca für allgemeine OpenMP-Probleme und OpenSpeedShop ist ebenfalls sehr nützlich.

Verwandte Themen