Код OpenMP, выполняемый в пуле потоков

Я думаю о дизайне, в котором пул потоков будет выполнять блоки кода, которые могут содержать операторы OpenMP (в основном параллельно). (Аналогично: Как справиться с конфликтом пула потоков OpenMP Наверное). Мой вопрос заключается в том, вызовет ли это проблемы или приведет к плохой производительности, если параллельная область OpenMP каждый раз выполняется другим потоком.

изменить:

Целью будет Linux (gcc) и Windows (msvc).

Я проверю его, когда будет готов мой первый прототип (на который повлияют ответы, которые я получу здесь).

Вот простой пример:

class Task
{
public:
    void doTask()
    {
        #pragma omp parallel
        {
            // do work in parallel
        }
    }
};

Теперь представьте, что вы создаете экземпляр Task и передаете его пулу потоков (thread-0,..., thread-n). Один поток выполняет doTask(). Позже вы снова передаете тот же объект Task в пул потоков, и снова ... . Таким образом, doTask() (и параллельный раздел) будут выполняться разными потоками. Интересно, эффективно ли это обрабатывается OpenMP (например, потоки для раздела не воссоздаются каждый раз).


person tauran    schedule 28.01.2011    source источник
comment
По моему опыту оптимизации кода, есть единственный способ узнать, будет ли что-то улучшать производительность: протестировать это. Думать и создавать гипотезы о том, что что-то работает медленно или нет, полезно только в том случае, если реализация слишком сложна. Создайте реалистичную тестовую демонстрацию и протестируйте ее.   -  person Vitor Py    schedule 28.01.2011


Ответы (1)


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

Что я могу сказать, так это то, что вы можете или не можете заставить это работать. Спецификация OpenMP, как и большинство других моделей многопоточности, ничего не говорит о том, как и будут ли модели «хорошо работать вместе». Например, несмотря на то, что некоторые реализации OpenMP используют pthreads для базовой реализации, если реализация не выполнила какую-либо работу, пользователь не может напрямую вызвать библиотеку pthreads и заставить ее работать вместе с OpenMP. Текущим примером этого является ошибка gcc 42616 (цикл OMP внутри pthread приводит к сбою). Другой пример — Intel, чей компилятор поддерживает множество параллельных моделей, но приложил немало усилий, чтобы заставить их работать вместе. Поскольку вы не сказали, какой компилятор вы собираетесь использовать, все, что я могу сказать, это попробовать небольшой пример кода, чтобы увидеть, работает ли он, прежде чем браться за что-то масштабное.

Я пробовал что-то подобное в прошлом. Я использовал pthreads, которые затем использовали конструкции OpenMP. Я обнаружил, что для моего приложения это работает нормально. Каждый pthread считался начальным потоком при обнаружении параллельной области OpenMP. Затем среда выполнения OpenMP создала дополнительные потоки для региона и запустила этот регион. Поскольку большинство реализаций OpenMP не уничтожают потоки, а помещают их в свободный пул для повторного использования при обнаружении другого региона, накладные расходы казались нормальными, но тогда у меня было много работы в этом регионе. Так что это может сработать, но вы должны быть осторожны.

person ejd    schedule 29.01.2011
comment
Спасибо. Подводя итог, если вы хотите быть в полной безопасности, конструкции OpenMP должны выполняться только в основном потоке. Но из сообщения об ошибке я понимаю, что это должно работать и ничего не запрещается (по крайней мере, не для gcc). - person tauran; 31.01.2011