Я изучил OpenMP, используя Тему Маттерсона, примечания к лекции , и он привел пример ложного обмена, как показано ниже.Код прост и используется для вычисления числа пи из числового интеграла 4,0 / (1 + x * x) с диапазоном х от 0 до 1. Код использует вектор для хранения значения 4,0 / (1 + х * х)для каждого x от 0 до 1, затем сложите вектор в конце:
#include <omp.h>
static long num_steps = 100000;
double step;
#define NUM_THREADS 2
void main()
{
int i, nthreads; double pi, sum[NUM_THREADS];
step = 1.0/(double)num_steps;
omp_set_num_threads(NUM_THREADS);
#pragma omp parallel
{
int i, id, nthrds;
double x;
id = omp_get_thread_num();
nthrds = omp_get_num_threads();
if (id == 0) nthreads = nthrds;
for (i=id, sum[id]=0.0; i<num_steps; i=i+nthrds){
x = (i+0.5)*step;
sum[id] += 4.0/(1.0+x*x);
}
}
for (i=0; pi=0.0; i<nthreads;i++) pi += sum[i]*step;
}
У меня есть несколько вопросов о ложном разделении из этого примера:
- Является ли ложное разделение вызваннымтем, что задание на запись в массив периодически делится между двумя потоками, то есть [thread0, thread1, thread0, thread1, ...]?Если мы используем
#pragma omp parallel for
, то массив будет разделен на [thread0, thread0, thread0, ...., thread1, thread1, thread1, ...], тогда у нас все еще будет ложное совместное использование, теперь, когда адресдоступ из каждого потока находится далеко друг от друга? - Если у меня есть задание, которое использует
#pragma omp parallel for
для записи в выходной вектор, который соответствует соотношению 1: 1 с моим входным вектором (например, входматрица предикторов и выходной вектор является предсказанием), тогда когда мне нужно беспокоиться о ложном обмене?