2012-04-01 3 views
1

в мой предыдущий вопрос Shared vectors in OpenMP было указано, что один может позволить Diferent темы читать и писать на общий вектор, пока различные темы, получить доступ к различным элементам вектора. Что делать, если разные потоки должны читать все (так иногда одни и те же) элементы вектора, как в следующем случае?Общие векторы в OpenMP 2

#include <vector> 

int main(){ 

vector<double> numbers; 
vector<double> results(10); 
double x; 

//write 25 values in vector numbers 
for (int i =0; i<25; i++){ 
    numbers.push_back(cos(i)); 
} 

#pragma omp parallel for default(none) \ 
shared(numbers, results) \ 
private(x) 
    for (int j = 0; j < 10; j++){ 
     for(int k = 0; k < 25; k++){ 
      x += 2 * numbers[j] * numbers[k] + 5 * numbers[j * k/25]; 
     } 
     results[j] = x;  
    } 

    return 0; 

} 

Будет ли это распараллеливание быть медленным, потому что только один поток одновременно может прочитать любой элемент вектора или это не так? Могу ли я решить проблему с пунктом firstprivate(numbers)?

Будет ли иметь смысл создавать массив векторов, чтобы каждый поток получал свой собственный вектор?

Например:

vector<double> numbersx[**-number of threads-**]; 

ответ

2

Чтение элементов одного и того же вектор из нескольких потоков не является проблемой. В вашем коде отсутствует синхронизация, поэтому к ним будут доступны одновременно.

С размером векторов, с которыми вы работаете, у вас также не будет проблем с кешем, хотя для больших векторов вы можете получить некоторые замедления из-за шаблона доступа к кешу. В этом случае отдельные копии данных с номерами повысят производительность.

+0

Спасибо за ваш ответ. Фактически вектор, который я действительно хочу использовать, может иметь до 67 * 10^6 записей (с двойным или плавающим типом данных). Так я должен делать копии и как? Что вы имеете в виду: «нет синхронизации в вашем коде»? – user1304680

+0

@ user1304680, похоже, что вы новичок в мультирадиции, поэтому я бы предложил прочитать дополнительную справочную информацию. Вкратце, синхронизация - это способ ограничить доступ к ресурсу, чтобы несколько потоков могли его прочитать и изменить. Это способ обеспечить логическую корректность, но он убивает параллелизм. Синхронизация осуществляется посредством атомных операций, критических секций, мьютексов. –

+0

@ user1304680, я бы предложил НЕ делать копию для начала и проверки масштабирования производительности. Если производительность не масштабируется с количеством ядер, вы можете посмотреть на оптимизацию доступа к кешу. –

1

лучший подход:

#include <vector> 

int main(){ 

vector<double> numbers; 
vector<double> results(10); 

//write 25 values in vector numbers 
for (int i =0; i<25; i++){ 
    numbers.push_back(cos(i)); 
} 

#pragma omp parallel for 
    for (int j = 0; j < 10; j++){ 
     double x = 0; // make x local var 
     for(int k = 0; k < 25; k++){ 
      x += 2 * numbers[j] * numbers[k] + 5 * numbers[j * k/25]; 
     } 
     results[j] = x; // no race here  
    } 

    return 0; 

} 

будет медленным из-за своего рода тем, что там не так много работы, чтобы поделиться

+0

спасибо. Я вижу, как вы объявляете x внутри цикла, это уже обсуждалось в http://stackoverflow.com/questions/9953905/shared-vectors-in-openmp, но, тем не менее, это все равно, так как результаты векторов и «числа» неявно разделены, не так ли? Возможно, не так много работы, но мой вопрос состоял в том, что в целом распараллеливание будет медленным, потому что разные потоки читают одни и те же элементы векторных «чисел». – user1304680

+0

чтение вряд ли будет проблемой производительности, запись может быть связана с ложным совместным использованием (google). вы можете решить его, разбивая внешний контур. – Anycorn

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