Подтвердить что ты не робот

Имеют ли pthreads какие-либо преимущества перед GCD?

Недавно узнав о Grand Central Dispatch, я нашел многопоточный код довольно интуитивным (с GCD). Мне нравится тот факт, что блокировки не требуются (и тот факт, что он использует блокированные структуры данных внутри), и что API очень прост.

Теперь я начинаю изучать pthreads, и я не могу не быть немного ошеломленным сложностью. Связывание потоков, мьютексы, переменные условия - все эти вещи не нужны в GCD, но имеют много вызовов API в pthreads.

Имеет ли pthreads какие-либо преимущества перед GCD? Это более эффективно? Существуют ли случаи обычного использования, когда pthreads могут делать то, что GCD не может сделать (исключая программное обеспечение на уровне ядра)?

Что касается межплатформенной совместимости, я не слишком обеспокоен. В конце концов, libdispatch является открытым исходным кодом, Apple представила свои изменения закрытия в качестве исправлений для GCC, clang поддерживает закрытие и уже (e.x. FreeBSD), мы начинаем видеть некоторые не-Apple реализации GCD. Меня больше всего интересует использование API (конкретные примеры будут замечательными!).

4b9b3361

Ответ 1

Это огромное чувство, которое вы испытываете. Именно поэтому был изобретен GCD.

На самом базовом уровне есть потоки, pthreads - это POSIX API для потоков, поэтому вы можете писать код в любой совместимой ОС и ожидать, что он будет работать. GCD построен поверх потоков (хотя я не уверен, что они фактически использовали pthreads как API). Я считаю, что GCD работает только на OS X и iOS, что в двух словах является его основным недостатком.

Обратите внимание, что проекты, которые сильно используют потоки и требуют высокой производительности, реализуют собственную версию пулов потоков. GCD позволяет вам избежать (повторно) изобретать колесо в разное время.

Ответ 2

Я иду с другого направления: начал использовать pthreads в своем приложении, которое я недавно заменил на С++ 11 std::thread. Теперь я играю с конструкциями более высокого уровня, такими как псевдо-boost threadpool и даже более абстрактными, Intel Threading Building Blocks. Я бы подумал, что GCD будет на уровне или даже выше, чем TBB.

Несколько комментариев:

  • imho, pthread не сложнее, чем GCD: в базовом ядре pthread фактически содержит очень мало команд (только несколько: использование только тех, которые упоминаются в OP, даст вам 95% + функциональности, которая вам когда-либо понадобится). Как любая библиотека нижнего уровня, это то, как вы их объединяете и как вы используете ее, которая дает вам свою силу. Не забывайте, что в конечном итоге библиотеки, такие как GCD и TBB, будут вызывать библиотеку потоков, такую ​​как pthreads или std::thread.
  • иногда, это не то, что вы используете, но как вы его используете, что определяет успех и неудачу. Как сторонники библиотеки, TBB или GCD расскажут вам обо всех преимуществах использования их библиотек, но пока вы не попробуете их в реальном контексте приложения, все это имеет теоретическое преимущество. Например, когда я читал о том, как легко было использовать мелкозернистый parallel_for, я сразу же использовал его в задаче, для которой, как я думал, может выиграть от parallelism. Естественно, меня тоже привлек тот факт, что TBB будет обрабатывать все детали оптимальной балансировки нагрузки и распределения потоков. Результат? TBB занял в пять раз больше, чем однопоточная версия! Но я не виню TBB: в ретроспективе это, очевидно, случай неправильного использования parallel_for: когда я читал мелкую печать, я обнаружил накладные расходы, связанные с использованием parallel_for, и полагал, что в моем случае затраты на контекст- переключение и добавление вызовов функций перевешивают преимущества использования нескольких потоков. Поэтому вы должны профилировать свой случай, чтобы узнать, какой из них будет работать быстрее. Возможно, вам придется реорганизовать свой алгоритм, чтобы использовать меньшие накладные расходы.
  • Почему это происходит? Как pthread или нет потоков быстрее, чем GCD или TBB? Когда дизайнер разрабатывает GCD или TBB, он должен сделать предположения о среде, в которой будут выполняться задачи. Фактически, библиотека должна быть достаточно общей, чтобы разработчик мог обрабатывать странные, непредвиденные варианты использования. Эти общие реализации не придут бесплатно. С другой стороны, библиотека будет запрашивать оборудование и текущую рабочую среду, чтобы лучше выполнять балансировку нагрузки. Будет ли это работать в вашу пользу? Единственный способ узнать, попробовать это.
  • Есть ли какая-либо польза для изучения библиотек более низкого уровня, таких как std::thread, когда доступны библиотеки более высокого уровня? Ответ - громкое ДА. Преимущество использования библиотек более высокого уровня - абстракция от деталей реализации. Недостатком использования библиотек более высокого уровня также является абстракция от деталей реализации. При использовании pthreads я в высшей степени осведомлен о совместном состоянии и времени жизни объектов, потому что, если я опустил свою защиту, особенно в проекте от среднего до большого размера, я могу очень легко получить условия гонки или ошибки памяти. Уходят ли эти проблемы, когда я использую библиотеку более высокого уровня? На самом деле, нет. Похоже, мне не нужно думать о них, но на самом деле, если я получу неаккуратность с этими деталями, реализация библиотеки также потерпит крах. Таким образом, вы обнаружите, что, если вы понимаете конструкции нижнего уровня, все эти библиотеки действительно имеют смысл, потому что в какой-то момент вы будете думать об их реализации самостоятельно, если используете вызовы более низкого уровня. Конечно, в этот момент обычно лучше использовать проверенный временем и отлаженный вызов библиотеки.

Итак, позвольте сломать возможные реализации:

  • TBB/GCD вызовы библиотеки: наибольшая польза для начинающих потоков. Они имеют более низкие барьеры для входа по сравнению с обучением библиотек более низкого уровня. Однако они также игнорируют/скрывают некоторые из ловушек использования многопоточности. Динамическая балансировка нагрузки сделает ваше приложение более портативным без дополнительного кодирования с вашей стороны.
  • pthread и std::thread звонки: на самом деле очень мало вызовов, чтобы учиться, но правильно их использовать, уделяя внимание деталям и глубокому пониманию того, как работает ваше приложение. Если вы можете понимать потоки на этом уровне, API-интерфейсы библиотек более высокого уровня, безусловно, будут иметь больше смысла.
  • однопоточный алгоритм: не будем забывать о преимуществах простого однопоточного сегмента. Для большинства приложений один поток легче понять и гораздо менее подвержен ошибкам, чем многопоточность. Фактически, во многих случаях это может быть соответствующий выбор дизайна. Дело в том, что реальное приложение проходит через различные многопоточные фазы и однопоточные фазы: не может быть необходимости многопоточно все время.

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

О, и ОП спросил о случаях, когда thread_pool не подходит. Простой случай: если у вас есть жесткий цикл, который не требует много циклов на цикл для вычисления, использование thread_pool может стоить больше, чем выгоды без серьезной переделки. Также имейте в виду накладные расходы на вызовы функций, такие как lambda через пулы потоков, и использование одного жесткого цикла.

Для большинства приложений многопоточность - это своего рода оптимизация, поэтому делайте это в нужное время и в нужном месте.

Ответ 3

GCD - это технология Apple, а не совместимая с большинством платформ; pthread доступны практически обо всем: от OSX, Linux, Unix, Windows, включая этот toaster

GCD оптимизирован для пула потоков parallelism. Pthreads (как вы сказали) очень сложные строительные блоки для parallelism, вам остается разработать свои собственные модели. Я очень рекомендую собрать книгу по этой теме, если вам интересно узнать больше о pthreads и разных моделях parallelism.

Ответ 4

Как любой декларативный/вспомогательный подход, например openmp или Intel TBB GCD должен быть очень хорош в неловко параллельных проблемах и, вероятно, легко будет бить наивную ручную pthread-ed параллельную сортировку. Я бы предположил, что вы все еще изучаете pthreads. Вы лучше поймете concurrency, вы сможете применить правильный инструмент в каждой конкретной ситуации, и если ни для чего другого - там тонна кода на основе pthread - вы сможете прочитать "устаревший" код.

Ответ 5

Обычная: 1 задача на реализацию Pthread использует мьютексы (функция ОС).
НОД: 1 на блок, сгруппированные в очереди. 1 поток на виртуальный процессор может получить очередь и работать без мьютексов через все задачи. Это уменьшает накладные расходы на потоки и накладные расходы на мьютексе, что должно повысить производительность.

Ответ 6

GCD реферат потоков и дает вам очереди отправки. Он создает потоки, которые он считает необходимыми, принимая во внимание количество доступных процессорных ядер. GCD является открытым исходным кодом и доступен через библиотеку libdispatch. FreeBSD включает в себя libdispatch от 8.1. Блоки GCD и C являются вкладами мэра от Apple в сообщество программирования C. Я никогда не использовал бы ОС, которая не поддерживает GCD.