Захватывая нить, и для ее завершения требуется много сотен машинных циклов. Но это только начало. Контекст переключается между потоками, которые должны произойти, если потоки делают что-нибудь полезное, будут многократно потреблять еще много сотен машинных циклов. Контекст выполнения всех этих потоков будет потреблять много байтов памяти, что, в свою очередь, испортит многие линии кеша, что помешает усилиям ЦП для еще одного большого количества сотен машинных циклов.
На самом деле, делать что-либо с многозадачностью является отличным потребителем многих сотен машинных циклов. Многозадачность становится прибыльной только с точки зрения Потребление энергии CPU, когда вам удается получить достаточное количество процессоров, работающих на кусках данных, которые концептуально независимы (поэтому параллельная обработка не будет угрожать их целостности) и достаточно большой, чтобы показать чистую прибыль по сравнению с монопроцессорной версией.
Во всех других случаях, многозадачный по своей сути неэффективен во всех областях, кроме одного: реактивности.Задача может очень быстро и точно реагировать на внешнее событие, которое в конечном итоге происходит от некоторого внешнего компонента H/W (будь то внутренние часы для таймеров или ваш контроллер WiFi/Ethernet для сетевого трафика).
Эта способность ждать внешних событий, не тратя впустую процессор, - это то, что увеличивает общую эффективность процессора. Вот и все.
С точки зрения других производительности параметров (потребление памяти, потери времени внутри вызовов ядра и т.д.), запускающего новый поток всегда чистый убыток.
В двух словах, искусство многозадачности программирования сводится к тому:
- идентификации внешнего ввода/вывода потоков вам придется обрабатывать
- принимая требования реактивности во внимание (напомним, что более реактивная = меньше CPU/память эффективна в 99% случаев)
- настройка обработчиков для необходимых событий с разумной эффективностью/простотой компрометации обслуживания.
Многопроцессорные архитектуры добавляют новый уровень сложности, поскольку любая программа теперь может рассматриваться как процесс, имеющий несколько внешних процессоров под рукой, которые могут использоваться в качестве дополнительных источников питания. Но ваша проблема, похоже, не имеет ничего общего с этим.
Мера эффективности многозадачной будет в конечном счете, зависит от количества внешних событий данная программа, как ожидается, чтобы справиться с одновременно и в пределах данного набора пределов реактивности.
Наконец-то я прихожу к вашему конкретному вопросу.
Чтобы реагировать на внешние события, запускать задачу каждый раз, когда новая ветка или кусочек мертвого насекомого должна перемещаться вокруг муравейника, это очень грубый и неэффективный подход.
В вашем распоряжении много мощных инструментов синхронизации, которые позволят вам реагировать на кучу асинхронных событий из одного контекста задачи с оптимальной эффективностью (практически) без затрат.
Как правило, блокировка ожидает нескольких входов, например, unix-приправленный select()
или Microsoft WaitForMultipleEvents()
.
Использование этих функций даст вам повышение производительности, которое несравнимо больше, чем несколько десятков циклов процессора, которые вы могли бы выжать из этого проекта оптимизации вашей задачи и результатов.
Таким образом, мой ответ: не беспокойтесь об оптимизации настройки нити. Это не проблема.
Ваше время было бы лучше потратить на переосмысление вашей архитектуры, чтобы несколько хорошо продуманных потоков могли заменить орды бесполезных процессоров и палочек памяти вашего текущего дизайна.
Вы случайно слово? Вернуть значение из потока, не так ли? –
? что вы имеете в виду? да – Luka
да, но я хочу самый эффективный способ – Luka