Я пишу программу на C, использующую pthreads для вычисления паттерна волнового фронта на двумерной матрице.Чтобы добиться хорошей производительности, я распределяю несколько строк в каждом потоке чередующимся образом, например так:
thread 0 ------------------
Тема 1 ------------------
Тема 2 ------------------
Тема 3 ------------------
Тема 0 ------------------
Тема 1 ------------------
Тема 2 -----------------
поток 3 ------------------
и т. Д.
В этом вычислении я думаю, что этотолько жизнеспособное разбиение, поскольку каждому потоку нужны новые значения, вычисленные в каждой строке, и они не могут двигаться дальше, пока они не станут доступны.Теперь выгода заключается в том, что потоку 1 нужны значения, вычисленные потоком 0 в его строке, поэтому он должен отставать от потока 0 и не опережать его.Для этого я делю каждый ряд на части и защищаю каждый кусок критическим разделом.Вычисления выполняются следующим образом:
поток 0 -----------
поток 1 ------
поток 2 ---
так, что всегда ряд i должен отставать от ряда i - 1. Надеюсь, вы понимаете идею.Я реализовал эту идею и тестирую ее на машине, которая представляет собой двухъядерную систему.Я испытываю странное поведение.Результаты рассчитываются правильно, но время выполнения колеблется в любом месте от 8 раз меньше, чем последовательное время и до больше, чем последовательное время.Практически, последовательное время для матрицы 12000 x 12000 составляет 16 секунд, а время параллельного запуска составляет от 2 до 17 секунд и часто отличается в двух последовательных прогонах.
Моя первоначальная идея заключалась в том, что эта проблема оченьчувствительность к локальности, поэтому, конечно, я могу получить плохую производительность, скажем, поток 0 и поток 1 запланированы на разных физических процессорах.Оглядываясь в / proc / cpuinfo, я пришел к выводу, что ядра отображаются так, что 0, 2, 4, 6 находятся на процессоре 0, а 1, 3, 5, 7 - на процессоре 1. Затем, при создании потока, я имеюиспользовал pthread_setaffinity_np, чтобы установить сродство к потокам на правильных ядрах.Однако ничего не меняется.Я также попытался использовать pthread_attr_setaffinity_np, а также sched_setaffinity, но получаю то же случайное время выполнения.
Либо ядро игнорирует мои вызовы аффинности, либо это не проблема.Я действительно надеюсь, что кто-то может помочь мне, поскольку у меня закончились идеи.Спасибо.