omp C код - l oop процесс замедляется до сканирования с добавленными потоками - PullRequest
0 голосов
/ 13 марта 2020

Я просматривал множество сообщений о переполнении стека, пытаясь выяснить, что происходит в моей программе, но безрезультатно. У меня есть алгоритм, который я считаю отличным кандидатом на распараллеливание. Этот алгоритм содержится в вызове функции, который заключен в один для l oop.

#pragma omp parallel default(none) shared(fci, weightSet, numWeightSets, i)
    {
#pragma omp for 
        for(i = 0; i < numWeightSets; i++) {
            fci->results[i] = runWeightSet(fci, weightSet[i]);
        }
    }
  • fci - это большая структура с некоторыми данными временных рядов, встроенными в
  • каждый вызов runWeightSet () использует другой набор весов, содержащийся в weightSet [i]
  • первое, что делает runWeightSet (), это выделяет место для произведения данных временного ряда и weightSet [i] данные вместе с кучей промежуточных переменных; данные временных рядов читаются всеми потоками, но
  • эта часть происходит довольно быстро во всех многопоточных сценариях ios
  • затем вводится вложенный l oop, в котором есть много вычислений и чтение / запись в выделенную память, но только в эту память, и больше никаких операций чтения из общих данных временных рядов.

На нашем 64-ядерном компьютере я получаю следующее приблизительное среднее время выполнения для runWeightSet () (N = количество ядер, секунд = среднее время выполнения):

N секунд
1 230
2 240
4 250
8 260
11 270
16 300
32 1200
64 9000

Я подозреваю, что у меня есть какое-то узкое место чтения / записи памяти, которое становится вредным когда я добавляю много процессорных ядер. Я попытался запустить perf на нем, но я не совсем уверен, что делать с выводом. Любые идеи или предложения будут наиболее цениться.

-Джим

1 Ответ

0 голосов
/ 15 марта 2020

Проблема, почему он так плохо масштабируется, вероятно, внутри метода runWeightSet, но мы не узнаем, пока вы не покажете его нам;).

Однако попробуйте удалить первую #pragma и заменить второй с #pragma omp parallel for. i определенно не должен использоваться совместно, у вас будут часто происходить состояния гонки, поскольку потоки пытаются увеличить его и использовать для доступа к взвешенным сетам. Он должен быть локальным (обеспечивается использованием конструкции omp for. Поэтому, возможно, это приводит к неправильному поведению runWeightSet.

...