Я второе замечание Уилла Хартунга. Вы можете просто кормить их одной задачей за раз (или несколькими задачами за раз, в зависимости от того, много ли у вас накладных расходов, то есть, если отдельные задачи обычно выполняются очень быстро по сравнению со стоимостью запуска / утилизации потоков). Ваши последующие комментарии эффективно объясняют, что ваши «потоки» несут большие затраты на создание, и, следовательно, вы хотите однократно выполнить их с максимально возможной работой, вместо того, чтобы тратить время на создание новых «потоков», каждый из которых питает небольшой объем работы.
Во всяком случае ... собирается на math question
...
Если вы хотите назначить задачи только один раз, используйте следующую формулу вместо ????????? в твоей логике, надо делать свое дело:
$Start = 1
+ (($i -1) * ($DefaultNumTasksAssigned + 1)
- (floor($i / ($Remainder + 1)) * ($i - $Remainder))
$End = $Start + $NumTasksAssigned -1
Формула объясняется следующим образом:
1 для того факта, что ваш дисплей / логика основана на единице, а не на нуле
Второй термин заключается в том, что мы обычно добавляем ($ DefaultNumTasksAssigned + 1) с каждой итерацией.
Третий член дает поправку за последние несколько итераций.
Его первая часть, (floor($i / ($Remainder + 1))
обеспечивает 0, пока $ i не достигнет первого потока
это не получает одно дополнительное задание, и 1 после этого.
Вторая часть выражает, сколько нам нужно исправить.
Формула для $ End проще, единственный трюк - минус 1, потому что значения Start и End являются включающими (например, между 1 и 19 есть 19 задач, а не 18)
Следующая слегка измененная часть логики также должна работать: она избегает «причудливой» формулы, сохраняя текущую вкладку переменной $ Start, а не пересчитывая ее каждый раз.
$NumTasks = 89
$NumThreads = 5
$Remainder = $NumTasks % $NumThreads
$DefaultNumTasksAssigned = floor($NumTasks / $NumThreads)
$Start = 1
For $i = 1 To $NumThreads
if $i <= $Remainder Then // fixed here! need <= because $i is one-based
$NumTasksAssigned = $DefaultNumTasksAssigned + 1
else
$NumTasksAssigned = $DefaultNumTasksAssigned
endif
$End = $Start + $NumTasksAssigned -1
print Thread $i: Tasks $Start-$End ($NumTasksAssigned tasks)
$Start = $Start + $NumTasksAssigned
Next
Вот приведенная выше Python-транскрипция
>>> def ShowWorkAllocation(NumTasks, NumThreads):
... Remainder = NumTasks % NumThreads
... DefaultNumTasksAssigned = math.floor(NumTasks / NumThreads)
... Start = 1
... for i in range(1, NumThreads + 1):
... if i <= Remainder:
... NumTasksAssigned = DefaultNumTasksAssigned + 1
... else:
... NumTasksAssigned = DefaultNumTasksAssigned
... End = Start + NumTasksAssigned - 1
... print("Thread ", i, ": Tasks ", Start, "-", End, "(", NumTasksAssigned,")")
... Start = Start + NumTasksAssigned
...
>>>
>>> ShowWorkAllocation(89, 5)
Thread 1 : Tasks 1 - 18 ( 18 )
Thread 2 : Tasks 19 - 36 ( 18 )
Thread 3 : Tasks 37 - 54 ( 18 )
Thread 4 : Tasks 55 - 72 ( 18 )
Thread 5 : Tasks 73 - 89 ( 17 )
>>> ShowWorkAllocation(11, 5)
Thread 1 : Tasks 1 - 3 ( 3 )
Thread 2 : Tasks 4 - 5 ( 2 )
Thread 3 : Tasks 6 - 7 ( 2 )
Thread 4 : Tasks 8 - 9 ( 2 )
Thread 5 : Tasks 10 - 11 ( 2 )
>>>
>>> ShowWorkAllocation(89, 11)
Thread 1 : Tasks 1 - 9 ( 9 )
Thread 2 : Tasks 10 - 17 ( 8 )
Thread 3 : Tasks 18 - 25 ( 8 )
Thread 4 : Tasks 26 - 33 ( 8 )
Thread 5 : Tasks 34 - 41 ( 8 )
Thread 6 : Tasks 42 - 49 ( 8 )
Thread 7 : Tasks 50 - 57 ( 8 )
Thread 8 : Tasks 58 - 65 ( 8 )
Thread 9 : Tasks 66 - 73 ( 8 )
Thread 10 : Tasks 74 - 81 ( 8 )
Thread 11 : Tasks 82 - 89 ( 8 )
>>>