2016-07-29 22 views
0

Ich habe nicht viel Erfahrung mit openmp.OpenMP für Schleife und Zeiger

Ist es möglich, den folgenden Code schneller zu machen, indem Sie einen For-Schleife über Zeiger statt Index verwenden?

Gibt es trotzdem den folgenden Code schneller machen?

Der Code multipliziert ein Array mit einer Konstanten.

Vielen Dank.

Code:

#include <iostream> 
#include <stdlib.h> 
#include <stdint.h> 
#include <vector> 
using namespace std; 
int main(void){ 
    size_t dim0, dim1; 
    dim0 = 100; 
    dim1 = 200; 
    std::vector<float> vec; 
    vec.resize(dim0*dim1); 
    float scalar = 0.9; 
    size_t size_sq = dim0*dim1; 
    #pragma omp parallel 
    {  
     #pragma omp for 
     for(size_t i = 0; i < size_sq; ++i){ 
      vec[i] *= scalar; 
     } 
    } 
} 

Serien Zeiger Schleife

float* ptr_start = vec.data(); 
float* ptr_end = ptr_start + dim0*dim1; 
float* ptr_now; 
for(ptr_now = ptr_start; ptr_now != ptr_end; ++ptr_now){ 
    *(ptr_now) *= scalar; 
} 
+0

In Ihrer Schleife sind nur 20.000 Werte vorhanden, und die CPU-Synchronisierung hat auch einen gewissen Mehraufwand. Haben Sie gemessen, wie schnell die Schleife mit und ohne OMP ist? Können Sie diese Ergebnisse teilen? –

+0

die tatsächliche Anordnung ist viel größer als diese. Ich möchte auch wissen, ob ich etwas getan habe, was Leistung schadet, weil ich openmp auch an anderen Orten verwenden werde. – rxu

+0

Wirklich generierter Code kann sich von dem unterscheiden, was Sie geschrieben haben. Haben Sie das Release-Programm mit allen Optimierungen disassembliert? PS .: Kann man mit OpenMP "size_t" als Indextyp verwenden? – ilotXXI

Antwort

1

Serien Zeiger Schleife sollte wie sein

size_t size_sq = vec.size(); 
float * ptr = vec.data(); 
#pragma omp parallel 
{  
    #pragma omp for 
    for(size_t i = 0; i < size_sq; i++){ 
     ptr[i] *= scalar; 
    } 
} 

ptr wird das gleiche für alle Threads also kein Problem da.

Als Erklärung, Data sharing attribute clauses (wikipedia):

geteilt: die Daten in einem parallelen Bereich geteilt wird, der gleichzeitig sichtbar und zugänglich von allen Threads bedeutet. Standardmäßig sind alle Variablen im Arbeitsbereich für die gemeinsame Nutzung freigegeben, mit Ausnahme des Iterationscounters .

privat: Die Daten in einer parallelen Region sind für jeden Thread privat, was bedeutet, dass jeder Thread eine lokale Kopie hat und diese als temporäre Variable verwendet. Eine private Variable wird nicht initialisiert und der Wert wird nicht für die Verwendung außerhalb der parallelen Region beibehalten. Nach Standard sind die Schleifeniterationsindikatoren in den OpenMP-Schleifenkonstrukten privat.

In diesem Fall ist i privat und ptr freigegeben.

+0

danke. Ich wusste nicht, dass die gleiche Adresse sich auf den gleichen Speicherblock über alle Threads beziehen würde. – rxu

+0

Wenn diese erfolgreich parallelisiert wird, wird die standardmäßige statische Planung jedem Thread einen fast gleich großen Chunk geben. – tim18

+0

Threads im selben Prozess teilen Adressraum außer Stapel: http://StackOverflow.com/Questions/1762418/Process-VS-Thread – rxu