LINUX.ORG.RU

Как установить причину замедления pthreads?

 ,


0

1

Есть некоторая чистая функция от натурального числа и я хочу применить её к числам от одного до миллиона.

Если сделать это в одном потоке, перебирая числа по порядку, это займёт ~30 секунд. Если же распараллелить всё на четыре потока таким образом, чтобы первый поток обрабатывал числа 1, 5, 9, ..., второй поток числа 2, 6, 10, ... и т.д., время работы программы, вопреки ожиданиям, составит ~45 секунд.

Однопоточная версия, запущенная в отдельном потоке, работает в 4-5 раз медленнее, чем версия вообще без потоков.

Все потоки совершенно независимы, никакой синхронизации, IO не используют. Память используется только на стеке.

Всё написано на чистом C, для многопоточности использую pthreads. Как можно хотя-бы приближённо понять причину такого замедления, желательно без чтения ассамблера?



Последнее исправление: devpony (всего исправлений: 3)

Ответ на: комментарий от anonymous

Код показать не могу, к сожалению. Вроде всё, что важно - описал. А что ещё можно было бы почерпнуть из кода?

devpony
() автор топика

Как установить причину замедления pthreads?

использовать профайлер

/thread

waker ★★★★★
()

Как можно хотя-бы приближённо понять причину такого замедления

Профайлером, вестимо

annulen ★★★★★
()

Однопоточная версия, запущенная в отдельном потоке

Все потоки совершенно независимы, никакой синхронизации

А как в main осуществляется ожидание на завершение потоков? Не через busy loop?

gag ★★★★★
()
Ответ на: комментарий от annulen

Какой лучше подойдёт для задачи? gprof выдаёт мне одну строчку, что функция thread выполнялась 100% времени..

devpony
() автор топика
Ответ на: комментарий от gag

Да, все 4 ядра во время работы загружены на 100%.

devpony
() автор топика
Ответ на: комментарий от gag

А не запускается ли всё это под виндой с mingw32?

нет

А как в main осуществляется ожидание на завершение потоков? Не через busy loop?

for i in n_threads
{
    pthread_join(threads[i])
}
devpony
() автор топика
Ответ на: комментарий от devpony

Код показать не могу, к сожалению.

В коде самое секретное - это та

некоторая чистая функция от натурального числа

Замени её на что-нибудь тривиальное (но не пустышку) и прогони. Не будет проблемы - значит она в той функции. А если проблема сохранится, тогда код целиком с несекретной функцией можно было бы тут запостить, чтобы другие попробовали прогнать.

gag ★★★★★
()

Hyper threading включён?

anonymous
()

1. Сколько памяти используется одним потоком? Меньше чем кеш процессора? Возможно многопоточный вариант использует больше памяти и кеш процессора слабо помогает.

2. Код с чередованием имеет другую, более сложную структуру. Возможно компилятор использовал переменную в памяти вместо регистра или умножение вместо инкремента на один, другую проверку окончания цикла. Возможно процессор не угадывает переходы. Но это имеет значение только если само вычисление настолько тривиальное, что цикл имеет существенную часть во времени выполнения.

NULL
()

отключи оптимизацию и ещё раз сравни результаты.

есть вариант что математику внутри циклов с простым инкрементом (;;i++), компилятор оптимизировал, а с более сложным (;;i+=N) уже не смог

MKuznetsov ★★★★★
()

Во-первых, забинди каждый тред на отдельный процессор, шоп у тебя потоки туда-сюда не скакали, и не ломался кеш у процессора. Во-вторых, у тебя ведь процессоров не меньше чем тредов, да? Иначе ты только хуже сделаешь. Ну и плюсую perf.

kirk_johnson ★☆
()
Последнее исправление: kirk_johnson (всего исправлений: 1)
Ответ на: комментарий от gag

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

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

devpony
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.