Оптимальное количество элементов для хранения в очереди для пула потоков в .NET? - PullRequest
0 голосов
/ 03 декабря 2009

Я создаю механизм фоновой обработки, который поддерживает отбрасывание как обрабатываемых, так и обрабатываемых элементов. Это для использования в приложении winforms, которое потребует интенсивной обработки некоторых элементов ввода, поэтому я создаю механизм очереди, где я могу ставить в очередь элементы рабочей нагрузки, и когда они обрабатываются, я получаю уведомление с результатами.

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

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

Итак, вопрос в том, как мне рассчитать это число N, количество элементов, которые нужно поместить в очередь пула потоков и сохранить в ней.

Проблемы, которые я рассмотрел:

  • Возможно, я захочу поставить в очередь 2 * количество процессоров, которое, как я вижу, является типичным числом элементов, чтобы убедиться, что все процессоры работают
  • Однако, если фактическая обработка некоторых элементов выполняется сверхбыстро (что может произойти), то очередь в пуле потоков исчерпывается, прежде чем мой собственный класс сможет заполнить ее дополнительной работой, поэтому, возможно, я бы хотел, чтобы большее число избегать неполного использования процессоров
  • Должен ли я создать некоторую процедуру автонастройки для расчета оптимального числа на основе текущего времени, которое занимает каждый элемент, чтобы, если они все были сверхбыстрыми, число было намного выше, а если обработка занимала немного времени, оно должно оставаться низким?

Что вы думаете?

Новый : Хорошо, из-за одного из ответов я объясню немного больше. Каждый элемент, помещенный в очередь, помечается чем-то уникальным. Если я помещаю другой элемент в очередь с тем же ключом, что и существующий элемент, этот старый элемент считается «Отброшенным» и должен быть удален. Если элемент обрабатывается, свойство элемента рабочей нагрузки устанавливается в значение true, свойство IsDicarded, за которое метод обработки отвечает за вызов. Если он обнаружит выброшенный элемент, он должен завершиться досрочно, не возвращая результатов.

Возможно, мне стоит немного поэкспериментировать и попытаться просто сбросить все в пул потоков.

Новый вопрос : Есть ли ограничение на количество предметов, которые я могу поставить в очередь? Если нет, то это легко упростит мой класс.

Примечание : Когда я говорю «длительная обработка», я имею в виду порядка 1-10 секунд. Поток еще лучше для этого? Я вижу в Интернете заметки о том, что «обработка должна быть быстрой», но что такое «быстрая», никогда не упоминается. Здесь скорость порядка миллисекунд?

Ответы [ 2 ]

1 голос
/ 03 декабря 2009

Знаете ли вы, что Ami Bar Smart Thread Pool ?

Кажется, его реализация позволяет отменить необработанный элемент и динамически увеличивать потоки по мере необходимости, до жесткого ограничения; Я лично использую 100 * Environment.ProcessorsCount

1 голос
/ 03 декабря 2009

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

Количество операций, которые могут быть очередь в пул потоков ограничена только доступной памятью; Тем не менее пул потоков ограничивает количество темы, которые могут быть активными в обрабатывать одновременно. По умолчанию, ограничение составляет 250 рабочих потоков на Процессор и 1000 потоков завершения ввода / вывода.

Вы можете контролировать максимальное количество потоки с помощью GetMaxThreads и Методы SetMaxThreads.

http://msdn.microsoft.com/en-us/library/0ka9477y.aspx

...