2016-07-29 2 views
0

openmp에 대한 많은 경험이 없습니다.루프 및 포인터 용 OpenMP

인덱스 대신 for 루프 포인터를 사용하여 다음 코드를 더 빠르게 만들 수 있습니까?

다음 코드를 더 빨리 만들 수 있습니까?

코드는 배열에 상수를 곱합니다.

감사합니다.

코드 :

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은 그래서 아무 문제가 모든 스레드에 대해 동일합니다 같은

#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; 
     } 
    } 
} 

시리얼 포인터 루프는

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

루프에는 20,000 개의 값만 있고 CPU 동기화에는 약간의 오버 헤드가 있습니다. 루프의 속도와 OMP가없는 속도를 측정 했습니까? 그 결과를 공유 할 수 있습니까? –

+0

실제 배열은이 배열보다 훨씬 큽니다. 나는 또한 내가 다른 곳에서도 openmp를 사용할 것이기 때문에 내가 성능을 해치는 일을했는지 ​​알고 싶다. – rxu

+0

실제로 생성 된 코드는 작성한 코드와 다를 수 있습니다. 모든 최적화 된 릴리즈 프로그램을 분해 했습니까? 추신 : OpenMP에서'size_t '를 인덱스 유형으로 사용할 수 있습니까? – ilotXXI

답변

1

직렬 포인터 루프가 있어야한다. 설명으로서

, Data sharing attribute clauses (wikipedia) :

공유 : 병렬 영역 내의 데이터가 동시에 모든 스레드에 의해 표시되고 액세스 이 의미에서 공유된다. 기본적으로 작업 공유 영역의 모든 변수는 루프 반복 카운터를 제외하고 공유됩니다.

private : 병렬 영역 내의 데이터는 각 스레드에 전용이며 입니다. 이는 각 스레드가 로컬 복사본을 가지고 임시 변수로 사용함을 의미합니다. 개인 변수가 초기화되지 않고 값은 병렬 영역 밖에서 사용하기 위해 유지 관리되지 않습니다. 기본적으로 OpenMP 루프 구문의 루프 반복 카운터는 private입니다.

이 경우 i은 비공개이며 ptr입니다.

+0

. 동일한 주소가 모든 스레드에서 동일한 메모리 블록을 참조한다는 것을 알지 못했습니다. – rxu

+0

이것이 병렬 처리되면, 기본 정적 스케줄링은 각 스레드에 거의 동일한 크기의 청크를 제공합니다. – tim18

+0

동일한 프로세스의 스레드는 스택을 제외한 주소 공간을 공유합니다. http://stackoverflow.com/questions/1762418/process-vs-thread – rxu