Разбиение произвольного диапазона чисел на грубые разделы равного размера в C с использованием OpenMP - PullRequest
1 голос
/ 08 марта 2012

Я хотел бы разбить диапазон чисел на примерно равный размер в C, используя OpenMP. Например, если у меня диапазон от 7 до 24 и число потоков равно 8. Я бы хотел, чтобы первый поток начинался с 7 и заканчивался на 9. Второй поток начинался с 10 и заканчивался на 12. Третий поток начинался с 13 и конец в 14. Четвертый поток начинается в 15 и заканчивается в 16 и т. д. До тех пор, пока последний поток не начнется в 23 и не закончится в 24. Я написал следующий код, но он не получает ранее объясненных результатов. Мне интересно, есть ли что-то, что я пропустил, что я могу сделать, или есть более эффективный способ сделать это? Ваша помощь очень ценится.

Примечание к предопределенному объявлению переменных на основе приведенного выше примера:

first = 7
last = 24
size = 2 (which signifies the amount of numbers per thread)
r = 2    (r signifies remainder)
nthreads = 8
myid = is the thread ID in a range of 0 to 7

    if (r > 0)
    {
        if (myid == 0)
        {
            start = first + myid*size;
            end = start + size;
        }
        else if (myid == nthreads - 1)
        {
            start = first + myid*size + myid;
            end = last;
        }
        else 
        {
            start = first + myid*size + myid;
            end = start + size;
        }
    }
    else
    {
        start = first + myid*size;
        if (myid == nthreads - 1) end = last;
        else end = start + size - 1;
    }

Ответы [ 2 ]

2 голосов
/ 08 марта 2012

Насколько я помню, #pragma omp parallel for автоматически делит работу между потоками на равные порции, и в большинстве случаев это нормально.

Однако, если вы хотите сделать это вручную, вот фрагмент кода, который делает то, что вы хотите:

int len = last - first + 1;
int chunk = len / nthreads;
int r = len % nthreads;
if (myid < r) {
    start = first + (chunk + 1) * myid;
    end = start + chunk;
} else {
    start = first + (chunk + 1) * r + chunk * (myid - r);
    end = start + chunk - 1;
}

Если нет дополнительных ограничений, такое распределение действительно оптимально.

1 голос
/ 08 марта 2012
// assuming half-open interval
int n = ((end-begin)  + omp_get_num_threads() - 1)/omp_get_num_threads();
int first = begin + n*omp_get_thread_num();
int last = max(first + n, end);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...