2011-04-13 2 views
1

Я пишу многопоточное приложение C++. Когда поток A выполняет очень дорогостоящую операцию, он замедляет потоки B, C и D. Как я могу предотвратить это?C++ Многопотоковая скорость выполнения Slow-Down

+0

Сколько ядер имеет ваша система? Если у вас меньше 4 ядер, то некоторые ядра придется делиться между несколькими потоками, а это значит, что стоимость одного потока повлияет на остальные ... –

+0

У меня есть 4 ядра. Это intel i7. – rossb83

+2

4 ядра и одна нить замедляют другие? Либо вы неправильно измеряете, либо потоки логически блокируют друг друга (то есть, это не время вычисления, замедляющее его). Таким образом, «спать», вероятно, не поможет. –

ответ

2

В окнах вы можете использовать Sleep(0), чтобы освободить оставшуюся часть вашего таймлиса для других потоков, которые ждут вас.

+0

То есть семантика POSIX также – sehe

+0

Это то, что я бы предложил - _but_ будет замедлять поток A, поэтому не следует использовать, если вычисление критично по времени. – tom502

+0

Учитывая, что у него есть 4cores, невозможно накладные расходы процессора одного потока замедлить других, чтобы «спать» действительно помогло. Вероятно, у него есть некоторая плохая замкнутая семантика. * Возможно использование ложного обмена, но было бы трудно заметить с помощью тестов производительности * –

0

Трудно сказать, не видя кода, поэтому я могу дать вам совет снизить приоритет Thread A. Это можно сделать, используя функцию SetThreadPriority.

0

Обратите внимание, что вы можете установить приоритеты потоков (SetThreadPriority)

Кроме того, я советую в BackgroundWorker выбирает свою работу из очереди. Очередь может быть использована как способ удушения расчетов:

  • вы можете настроить, сколько «задачи» взяты из очереди на обработку одним маха
  • вы можете заблокировать очереди (использование семафоров + условие события), чтобы вы могли временно предотвратить сбор новых задач.
  • теперь вы можете распределить нагрузку между несколькими рабочими (например, если поток B, C, D временно бездействует, они могут начать поднимать отрабатывают нить А, очень полезно на четырехъядерной + рабочий стол)

$ 0,02

+0

Добавлено больше советов – sehe

0

есть несколько способов:

  • Как предложил RedX добавить Sleep(0) во внутреннем контуре Пронизывайте, чтобы иметь его дать время все чаще. Это дешевое и ленивое решение.
  • Лучше было бы изменить приоритет потока. Когда вы вызываете CreateThread, пройдите CREATE_SUSPENDED, чтобы поток не начинался немедленно. Затем вызовите SetPriorityClass, чтобы установить нить в нижний приоритет, а затем ResumeThread.
+0

При более низком приоритете он также будет прерван другими системными процессами.В режиме сна (0) вы все равно можете иметь приоритет для всех своих потоков и использовать «Сон», чтобы дать оставшуюся часть времени этим потокам. (Надеюсь, это имеет смысл) – RedX

+0

@RedX, ваш комментарий неправильный. Когда вы 'Sleep (0)' текущий исполняемый поток приостанавливается, но нет абсолютно никакой гарантии, что следующий поток будет запущен из вашего процесса. Таким образом, вы потенциально уступаете свое время системным потокам в любом случае. –

0

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

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