Ваш вопрос не дает достаточно контекста, чтобы можно было на него ответить, но я могу сделать некоторые предположения на основе предоставленных вами примеров дисплеев.
Похоже, у вас "одна очередь, несколько серверов"" настроить.Другими словами, у вас есть одна очередь FIFO и некоторое фиксированное число N заданий, которые могут обрабатываться в любой момент времени.Это верно?
Для вашего алгоритма, давайте предположим, что у вас есть следующая информация:
- Позиция нашей работы в очереди (позиция N означает, что впереди N рабочих мест)
- Размер нашей работы
- Размер каждой работы впереди нас в очереди
- Пул обрабатываемых работ с определенным максимальным размером N
- Размеркаждой обрабатываемой в данный момент работы
- Истекшее время для каждой работы, выполняемой в данный момент (сколько времени прошло с момента запуска этой работы)
Прежде всего, вам понадобится функция ExpectedJobDuration (jobsize)это вычисляет ожидаемое время обработки задания для заданного размера на основе статистики, показанной в вашей таблице «статус производительности».Это выглядит довольно просто.Учитывая размер работы, сначала выясните, к какой из пяти категорий размеров она относится (0: 0-1mb, 1: 1-5mb и т. Д.), Затем возьмите размер вашей работы и умножьте на среднее время, деленное на средний размеррабочие места в этой категории.Это даст вам оценку ExpectedJobDuration (jobsize), которая скажет вам, сколько времени требуется для выполнения задания заданного размера, при условии, что время задания пропорционально размеру задания для заданий в пределах определенного диапазона размеров.
Теперь, для задания заданного размера, которое уже выполняется в течение определенного времени ElapsedProcessingTime, как долго мы ожидаем, что оно будет выполнено?Простой ответ будет выглядеть примерно так:
ExpectedRemainingTime = ExpectedJobDuration(jobsize) - ElapsedProcessingTime.
Для заданий, сидящих в очереди, это будет в точности соответствовать ожидаемой продолжительности задания;для работ, которые уже обрабатываются, мы вычитаем время, в течение которого работа уже выполнялась.Однако, если есть случайные изменения во времени обработки задания, это не совсем правильно и может оказаться отрицательным.Это похоже на актуарную проблему: средняя продолжительность жизни человека составляет X лет, как долго мы ожидаем, что кто-то будет жить, если ему уже Y лет?Вам понадобится намного больше статистических данных, чтобы вычислить это, поэтому для практических целей, если ответ будет отрицательным, просто установите его на ноль.(Если кому-то 100 лет, а средняя продолжительность жизни человека составляет 90 лет, ожидайте, что он умрет в любой момент. Это не совсем правильно, но, возможно, в порядке первого приближения. Если вы не 100-летний человек, но еще не готовыумереть.: -))
Хорошо, теперь у нас есть способ вычислить, сколько времени должно занять каждое задание в очереди и сколько нужно времени, чтобы завершить уже выполняемые задания.
Если количество обрабатываемых в данный момент заданий меньше N (максимальное количество, которое может быть обработано в любой момент времени), наша работа может начаться сразу же.Таким образом, в этом случае у нас есть ответ - ожидаемая задержка до начала нашей работы равна нулю секунд.
Теперь давайте посмотрим на случай, когда мы находимся в позиции 0 в очереди.Это означает, что впереди нас в очереди нет, поэтому ожидаемое время для запуска - это минимум ExpectedRemainingTime для заданий в пуле обработки.
Теперь это дает нам основу для рекурсивной функции, котораявычисляет задержку до ожидаемого времени начала.
DelayUntilStart(jobPool, currentJob, queue) {
find minJob in jobPool with minimum ExpectedRemainingTIme
if currentJob is in position zero of queue
return expectedRemainingTime(minJob)
else
remove minJob from jobPool
pop the top job from the queue and put it in the jobPool
return ExpectedRemainingTime(minJob) + DelayUntilStart(jobPool, currentJob, queue)
done
}
Примечание - у нас может быть очень долгая работа в очереди - но это не значит, что мы должны ждать ее завершения.Нам просто нужно подождать, пока он попадет в пул обрабатываемых в данный момент заданий, а затем может быть выполнено более короткое задание, и мы попадем в пул.
Алгоритм, который я только что описал, будет приблизительным.Но это, вероятно, примерно так же хорошо, как вы получите без большой статистики о времени обработки заданий.В практических целях, держу пари, это сработало бы неплохо.