Перекрывающиеся вычисления и связь или ввод / вывод с использованием OpenMP - PullRequest
0 голосов
/ 01 октября 2018

Я работаю над проектом HPC, где я обрабатываю ТБ данных с диска.Основной поток, если он представлен путем импорта подмножества данных на каждом узле.Создание множества других данных и накопление результатов, а затем экспорт результатов.Ввод / вывод, который нужно сделать, велик и занимает почти столько же времени, сколько и вычисления.Я надеялся чередовать вычисления и общение.Я действительно знаю только OpenMP.Ниже приведен пример псевдокода моей попытки.Тем не менее, кажется, что разделы работают последовательно.

Есть ли способ заставить секции работать параллельно?Есть лучший способ сделать это?

while ( There are still blocks of work available ) {

#pragma  omp parallel sections num_threads(2)
{
    #pragma omp section
    {
        //Perform collective I/O 
        // Based on parallel HDF
        BigBlock block1 = ImportFunc();
    }

    #pragma omp section
    {
        while (While there are still subset blocks to process) {
            const SubSetBlock block2 = GenerateNextSubBlock(); //includes a parallel for loop

            #pragma omp parallel for default(shared) num_threads(omp_get_max_threads()-1)
            for (int i = 0; i < numVessels; ++i) {
                ProcessAllBlock2ItemsForABlock1Item(block1[i], block2);
            }

        }

    }
} //OMP Sections
}// while

Ответы [ 2 ]

0 голосов
/ 02 октября 2018

Если вы предпочитаете вложение, вам следует установить omp_set_max_active_levels(...) (по крайней мере, 2 в вашем случае) и omp_set_nested(true).

Однако я бы честно предложил вам использовать std::future, в этом случае он очень прост в использовании и будет запускать вашу функцию в отдельном потоке (чтобы быть уверенным, вы должны передать ее std::launch::async в качестве первогоаргумент).Как правило, он не такой капризный, как OpenMP, когда дело доходит до вложения.

Вызов будет выглядеть примерно так:

std::future<BigBlock> block1 = std::async(std::launch::async, ImportFunc, ...);

Где ... - это любые параметры, которые вы хотите передать ImportFunc.

Как только вам понадобятся данные, которые вы вызываете block1.get(), он будет ожидать завершения потока, если он этого не сделал, или просто вернет данные, если у него есть.В этот момент я бы предложил, чтобы у вас был конструктор перемещения (вы действительно не хотите копировать его, если он большой, тогда, опять же, у вас, вероятно, уже есть один для ImportFunc, или вы передаете указатели, но в этомВ этом случае убедитесь, что вы не delete, когда будущее разрушается, если вы создаете другой экземпляр BigBlock), и просто перемещаете его в другой экземпляр BigBlock (т. е. тот, над которым ваши потоки хотят работать).

0 голосов
/ 01 октября 2018

В моем ограниченном опыте с большими наборами данных я нашел STXXL весьма полезным.Он использует OpenMP под капотом и будет насыщать дисковый ввод-вывод, если вы сможете достаточно быстро передавать данные.

http://stxxl.org

Mike

...