2016-07-29 3 views
0

У меня нет большого опыта работы с openmp.OpenMP для цикла и указателя

Возможно ли сделать следующий код быстрее, используя указатель for for вместо указателя?

Есть ли способ сделать следующий код быстрее?

Код умножает массив на константу.

спасибо.

Код:

#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 значений, а также для синхронизации процессора. Вы оценили, насколько быстро цикл работает с OMP и без него? Можете ли вы поделиться этими результатами? –

+0

фактический массив намного больше, чем этот. Я также хочу знать, сделал ли я что-то, что ухудшает производительность, потому что я буду использовать openmp в других местах. – rxu

+0

Действительно сгенерированный код может отличаться от того, что вы написали. Вы разобрали программу выпуска со всеми оптимизациями? P.S .: Ваш OpenMP позволяет использовать 'size_t' в качестве типа индекса? – ilotXXI

ответ

1

цикл Последовательный указатель должен быть как

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 будет одинаковой для всех потоков, поэтому никаких проблем там.

В качестве объяснения, Data sharing attribute clauses (wikipedia):

совместно: данные в пределах параллельной области являются общим, что означает видимый и доступный для всех потоков одновременно. По умолчанию все переменные в области совместного использования совместно используются, за исключением счетчика итераций цикла .

закрытый: данные в параллельной области являются приватными для каждого потока, , что означает, что каждый поток будет иметь локальную копию и использовать его как временную переменную . Закрытая переменная не инициализируется, и значение не поддерживается для использования вне параллельной области. По умолчанию , счетчики итераций цикла в конструкциях цикла OpenMP: private.

В этом случае i является частным лицом и ptr.

+0

спасибо. Я не знал, что один и тот же адрес будет ссылаться на один и тот же блок памяти для всех потоков. – rxu

+0

Если это успешно распараллеливается, статическое планирование по умолчанию даст каждому потоку кусок почти равного размера. – tim18

+0

потоки в одном домене общего доступа к процессу, за исключением стека: http://stackoverflow.com/questions/1762418/process-vs-thread – rxu

Смежные вопросы