Идентификаторы потоков с PPL и параллельным распределением памяти - PullRequest
4 голосов
/ 03 апреля 2012

У меня есть вопрос о библиотеке Microsoft PPL и о параллельном программировании в целом. Я использую FFTW для выполнения большого набора (100 000) 64 x 64 x 64 FFT и обратных FFT. В моей текущей реализации я использую параллель для цикла и выделяю массивы хранения внутри цикла. Я заметил, что в этих случаях загрузка моего процессора составляет всего около 60-70%. (Обратите внимание, что это все же лучше, чем использование встроенных потоковых БПФ, предоставленных FFTW, которые я тестировал). Поскольку я использую fftw_malloc, возможно ли, что происходит чрезмерная блокировка, которая препятствует полному использованию?

В свете этого целесообразно ли предварительно распределять массивы хранения для каждого потока перед основным циклом обработки, чтобы в самом цикле не требовались блокировки? И если да, то как это возможно с библиотекой MSFT PPL? Я использовал OpenMP раньше, в этом случае достаточно просто получить идентификатор потока, используя предоставленные функции. Однако я не видел подобной функции в документации по PPL.

Ответы [ 2 ]

2 голосов
/ 04 апреля 2012

Я просто отвечаю на это, потому что никто еще ничего не публиковал.

Mutex (e) может нанести ущерб производительности, если требуется сильная блокировка.Кроме того, если требуется много (пере) распределения памяти, это также может снизить производительность и ограничить ее пропускной способностью памяти.Как вы сказали, предварительное распределение, с которым работают более поздние потоки, может быть полезным.Однако для этого требуется, чтобы у вас был фиксированный счетчик потоков и чтобы вы распределили свою рабочую нагрузку на все потоки.

Что касается функций PPL thread_id, я могу говорить только о Intel-TBB, который, однако, должен быть довольно похож на PPL.TBB - и я полагаю, также PPL - не говорит непосредственно о потоках, вместо этого они говорят о задачах, целью TBB было абстрагирование этих лежащих в основе деталей от пользователя, таким образом, оно не предоставляет функцию thread_id.

0 голосов
/ 04 ноября 2012

Используя PPL, у меня была хорошая производительность с приложением, которое выполняет много распределений, используя Concurrency::combinable для хранения структуры, содержащей память, выделенную для потока.

Фактически вам не нужно предварительно выделять, вы можете проверить значение вашей комбинируемой переменной с помощью ->local() и выделить его, если оно равно нулю. В следующий раз этот поток будет вызван.

Конечно, вы должны освободить память, когда все задачи выполнены, что можно сделать с помощью: с чем-то вроде:

combine_each([](MyPtr* p){ delete p; });
...