Как может быть реализован алгоритм циклического перебора, который работает в цикле навсегда?
for (int i = 0; ;i++){
roundRobinIndex = i % numberOfWorkers;
}
Проблемы с вышеуказанным способом в том, что integer overflow
проблема. Это также может быть реализовано с проверкой значения i
:
for (int i = 0; ;i++){
roundRobinIndex = i % numberOfWorkers;
if i == maxNumber{
i = 0;
}
}
Но этот путь кажется безобразным. Может быть, есть более элегантный способ?
Почему бы и нет ?
int numberOfWorkers = 10
int roundRobinIndex = numberOfWorkers - 1
while(true){
roundRobinIndex = (roundRobinIndex + 1) % numberOfWorkers
}
или с петлей
for (int i = 0; ;i = (i + 1) % numberOfWorkers){
roundRobinIndex = i;
}
Теперь мы можем избавиться от i
Избегая любого звонка по модулю, мы можем сделать:
constexpr int nextRR(int curIdx, int sz) {
if(curIdx==sz-1) {
return 0;
}
return curIdx+1;
}
for (int rrIndex = 0;;rrIndex = nextRR(rrIndex, sz)) {
// use rrIndex here ...
}
Это будет с точки зрения производительности более эффективным, чем любое основанное на модуле решение, если число рабочих не известно во время компиляции.
Обратите внимание, что nextRR
также может быть написано так, чтобы оптимизировать еще больше для платформ, где сравнение с 0 быстрее, чем сравнение с переменной:
constexpr int nextRR(int curIdx, int sz) {
if(curIdx==0) {
return sz-1;
}
return curIdx-1;
}
Для полноты (я согласен, что ответ pLopeGG более элегантный) — ваш способ будет работать отлично, если вы сделаете i
unsigned int
скорее, чем int
поскольку переполнение определено в стандарте для беззнаковых переполнений, но не подписано.
т.е.
for (unsigned int i = 0; ;i++){
roundRobinIndex = i % numberOfWorkers;
}
Почему бы не поставить %
в петлю?
for (int i = 0; ;++i, i %= numberOfWorkers)
{
}