Круговой алгоритм в цикле - PullRequest
0 голосов
/ 06 июля 2018

Как может быть реализован алгоритм циклического перебора, который работает в цикле навсегда?

for (int i = 0; ;i++){
    roundRobinIndex = i % numberOfWorkers;
}

Проблемы с вышеуказанным способом - проблема integer overflow. Это также может быть реализовано с проверкой значения i:

for (int i = 0; ;i++){
    roundRobinIndex = i % numberOfWorkers;
    if i == maxNumber{
        i = 0;
    }
}

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

Ответы [ 4 ]

0 голосов
/ 06 июля 2018

Почему бы не поместить % в цикл?

for (int i = 0; ;++i, i %= numberOfWorkers)
{
}
0 голосов
/ 06 июля 2018

Для полноты (я согласен, что ответ pLopeGG более элегантный) - ваш способ будет работать отлично, если вы сделаете i unsigned int, а не int, так как переполнение определено в стандарте для переполнений без знака, но не подписано.

е

for (unsigned int i = 0; ;i++){
    roundRobinIndex = i % numberOfWorkers;
}
0 голосов
/ 06 июля 2018

Во избежание любого звонка по модулю, мы можем сделать:

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;
}
0 голосов
/ 06 июля 2018

Почему бы и нет?

int numberOfWorkers = 10
int roundRobinIndex = numberOfWorkers - 1
while(true){
    roundRobinIndex = (roundRobinIndex + 1) % numberOfWorkers
}

или с петлей for

for (int i = 0; ;i = (i + 1) % numberOfWorkers){
    roundRobinIndex = i;
}

Теперь мы можем избавиться от i

...