2013-08-02 2 views
2

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

Но на практике неизменно один или два потока будут потребляться процессором в течение всего доступного времени. Мое собственное экспериментирование с семафорами/etc для управления выполнением показало, что это удивительно сложно исправить, поскольку я не могу заставить данный поток прекратить выполнение (включая использование «yield» из Control.Concurrent.)

Есть ли известный способ гарантировать, что произвольное количество потоков Haskell (а не потоков ОС) каждый получает примерно равное количество процессорного времени в течение (довольно короткого) времени настенных часов? В противном случае, хороший способ гарантировать, что несколько потоков, выполняющих идентичную итерацию, «по очереди» на определенное количество ядер, так что все ядра используются?

+0

Можете ли вы, чтобы ваши потоки регистрировались в центральной потоке планирования так часто ... скажем, каждые 1000 итераций или что-то в этом роде? –

+2

Попробуйте взглянуть на реализацию кооперативной нити [здесь] (http://www.haskellforall.com/2013/06/from-zero-to-cooperative-threads-in-33.html). Обратите внимание, что вы также можете оценить многие из этих «потоков» одновременно. – cdk

+1

Убедитесь, что значения, разделяемые между потоками, оцениваются (в [NF] (http://hackage.haskell.org/packages/archive/deepseq/latest/doc/html/Control-DeepSeq.html#t:NFData), например). Как вы точно измеряете, сколько процессорного времени получает каждый поток? –

ответ

3

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

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