буст стренд против одного потока - PullRequest
3 голосов
/ 15 декабря 2011

Поскольку нить не будет выполняться одновременно, в чем разница в производительности между нитью и одним потоком? Более того, блокировка не нужна для защиты общих данных в обработчике функции post, верно?

предположим, что приложение выполняет несколько заданий, ниже приведен пример кода.

strand.post(boost::bind(&onJob, this, job1));

void onJob(tJobType oType)
{
  if (oType == job1)
   // do something
  else if(oType == job2)
   // do something
}

Редактировать: я пытаюсь измерить задержку от сообщения, и вызов onJob довольно высок. Я хотел бы знать, есть ли способ уменьшить его

1 Ответ

11 голосов
/ 15 декабря 2011

A strand обычно работает лучше, чем один поток.Это связано с тем, что цепочка дает планировщику и логике программы больше гибкости.Однако различия, как правило, незначительны (за исключением особого случая, который я обсуждаю ниже).

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

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

Обратите внимание, что если выпросто один поток, выполняющий цепочку, вы не получите этих преимуществ.(Но, IMO, это глупый способ сделать что-то, если вы заботитесь о производительности на этом прекрасном уровне.)

В некоторых приложениях осторожное разбиение вашей программы на нити может значительно сократить количество требуемых операций блокировки.Объекты, доступ к которым возможен только в одной цепи, не нужно блокировать.Но вы все равно можете получить много преимуществ многопоточности.(Однако есть один большой недостаток - если какой-либо ваш код когда-либо блокирует, он остановит всю цепочку. Поэтому вы либо не должны возражать, если цепочка остановится, либо убедитесь, что ни один из ваших кодов не является критической цепьювсегда блокирует.)

В этом случае у вас может быть три нити, A, B и C, и одна нить может выполнять некоторую работу для нити A, некоторую для нити B, а другую для нити C сбез переключений контекста (и с горячими данными в кеше).Использование потока для каждой задачи потребует двух переключателей контекста для выполнения одной и той же работы, и каждая задача, скорее всего, не найдет данные в кеше.Если вы постоянно «передаете вещи» из цепочки в цепочку, цепочки могут значительно превзойти выделенные потоки.

Что касается вашего второго вопроса, блокировка не требуется, если к данным не обращаются в одном потоке, хотя это может бытьизменено в другой теме.Если все обращения к объекту осуществляются через одну цепочку, блокировки не нужны, поскольку цепочка может выполняться только в одном потоке за раз.Как правило, нити получают доступ к некоторым данным, к которым имеет доступ только эта нить, а некоторые - к другим потокам или прядям.

...