33

Вопрос по haskell, multithreading – Нужны ли пулы потоков для чистого кода на Haskell?

ВReal World Haskell, Глава 28, Программная транзакционная память, одновременная проверка веб-ссылки. Он выбирает все ссылки на веб-странице и нажимает на каждый из них запрос HEAD, чтобы выяснить, активна ли ссылка. Для создания этой программы используется параллельный подход, и делается следующее утверждение:

Мы можем'просто создайте один поток на URL, потому что это может перегружать наш ЦП или наше сетевое соединение, если (как мы ожидаем) большинство ссылок являются живыми и отзывчивыми. Вместо этого мы используем фиксированное количество рабочих потоков, которые выбирают URL-адреса для загрузки из очереди.

Я не до конца понимаю, зачем нужен этот пул потоков вместо использованияforkIO за каждую ссылку. AFAIK, среда выполнения Haskell поддерживает пул потоков и распределяет их соответствующим образом, поэтому я не вижу перегрузки процессора. Кроме того, вобсуждение параллелизма в списке рассылки на HaskellЯ нашел следующее утверждение, идущее в том же направлении:

Единственная парадигма, которая не имеет смысла в Haskell, - это рабочие потоки (поскольку RTS делает это для нас); вместо получения рабочего, просто forkIO вместо этого.

Требуется ли пул потоков только для сетевой части или для этого есть причина в ЦП?

<span>Пул необходим для контроля уровня параллелизма и управления им. Вы&#39;Вероятно, мы забыли о практических соображениях. Среда выполнения Haskell действительно неплохо поддерживает потоки пространства Haskell - они довольно легкие, и вы можете без проблем создавать тысячи из них. Но что произойдет, если вы возьмете список из 100К URL-адресов и просто разметите один за другим без &quot;объединив»? Вы&#39;Скорее всего, будут тысячи и тысячи соединений. У многих из них истечет время ожидания, в вашей системе закончатся файловые дескрипторы, и выСкорее всего, не хватит оперативной памяти при попытке обработать результаты.</span>

Mar 04, 2013, 4:48 AMотozataman

1ответ

23

Основная проблема, я полагаю, связана с сетью. Если у вас есть 10 000 ссылок и forkIO для каждой ссылки, то потенциально у вас есть 10 000 сокетов.Вы пытаетесь открыть сразу, что, в зависимости от того, как настроена ваша ОС, вероятно, выиграетЭто даже возможно, гораздо менее эффективно.

Однако тот факт, что у нас есть зеленые нити, которые получают "практически» запланировано через несколько потоков ОС (которые в идеале привязаны к отдельным ядрам) неЭто означает, что мы можем просто распределять работу случайным образом, независимо от использования процессора. Вопрос здесь нетак много, что планирование самого процессора выиграетне для нас, а для того, чтобы переключать контексты (даже зеленые) стоило циклов. Каждый поток, если он работает с разными данными, должен будет вытянуть эти данные в процессор. Если там'Достаточно данных, что означает извлечение вещей из кэша процессора. Даже если это отсутствует, это означает, что вытащить вещи из кэша в регистры и т.

Даже если проблема тривиально параллельна, она фактическиникогда правильная идея - просто разбить его как можно меньше и попытаться сделать это »все сразу".

RelatedQuestions