#multithreading #parallel-processing #tbb
#многопоточность #параллельная обработка #tbb
Вопрос:
У меня есть некоторый последовательный код, который я начал распараллеливать с помощью TBB от Intel. Моей первой целью было распараллелить почти все циклы for в коде (я даже распараллелил for внутри цикла for), и прямо сейчас, выполнив это, я получаю некоторое ускорение.Я ищу больше мест / идей / вариантов для распараллеливания…Я знаю, это может показаться немного расплывчатым без особого упоминания проблемы, но я ищу здесь общие идеи, которые я могу изучить в своем коде.
Обзор алгоритма ( следующий алгоритм выполняется на всех уровнях изображения, начиная с самого короткого и увеличивая ширину и возвышение на 2 каждый раз, пока вы не достигнете фактической высоты и ширин).
For all image pairs starting with the smallest pair
For height = 2 to image_height - 2
Create a 5 by image_width ROI of both left and right images.
For width = 2 to image_width - 2
Create a 5 by 5 window of the left ROI centered around width and find best match in the right ROI using NCC
Create a 5 by 5 window of the right ROI centered around width and find best match in the left ROI using NCC
Disparity = current_width - best match
The edge pixels that did not receive a disparity gets the disparity of its neighbors
For height = 0 to image_height
For width = 0 to image_width
Check smoothness, uniqueness and order constraints*(parallelized separately)
For height = 0 to image_height
For width = 0 to image_width
For disparity that failed constraints, use the average disparity of
neighbors that passed the constraints
Normalize all disparity and output to screen
Комментарии:
1. Диаграмма потока данных может помочь найти задачи, которые могут выполняться независимо, параллельно.
2. @rwong- Добавлен обзор. Дайте мне знать, если вы чего-то не понимаете.
Ответ №1:
Просто с некоторой точки зрения не всегда может быть целесообразно что-то распараллеливать.
То, что у вас есть цикл for, в котором каждая итерация может выполняться независимо друг от друга, не всегда означает, что вы должны это делать.
TBB требует некоторых накладных расходов для запуска этих циклов parallel_for, поэтому, если вы не выполняете цикл большое количество раз, вам, вероятно, не следует его распараллеливать.
Но, если каждый цикл чрезвычайно дорог (как в примере CirrusFlyer), тогда не стесняйтесь его распараллеливать.
Более конкретно, ищите случаи, когда накладные расходы на параллельные вычисления невелики по сравнению со стоимостью их распараллеливания.
Кроме того, будьте осторожны при выполнении вложенных циклов parallel_for, так как это может стать дорогостоящим. Возможно, вы захотите просто распараллелить внешний цикл for.
Комментарии:
1. Вложенные циклы parallel_for прекрасно использовать в TBB. Конечно, есть некоторые накладные расходы, но настройки TBB по умолчанию (в частности, auto_partitioner) пытаются минимизировать накладные расходы. Если внутренний цикл будет выполняться быстрее на двух ядрах, его распараллеливание может иметь смысл, особенно если внешний цикл недостаточно хорошо сбалансирован.
2. @Alexey: Я хочу сказать, что если ваш цикл очень дешевый и в нем не так много итераций, обычно нет смысла делать его параллельным. Конечно, если время выполнения внешнего цикла может меняться, возможно, имеет смысл распараллелить оба цикла, но в целом вам следует быть осторожным и всегда измерять, помогает ли это.
3. Я согласен; и на самом деле то, что вы сказали, верно для параллелизма на любом уровне, а не только для вложенных элементов. Я просто хотел подчеркнуть, что TBB довольно хорошо поддерживает вложенный параллелизм.
Ответ №2:
Глупый ответ — это все, что отнимает много времени или является итеративным. Я использую параллельную библиотеку задач Microsoft .NET версии 4.0, и одной из интересных особенностей их настройки является ее «выраженный параллелизм». Интересный термин для описания «попытки параллелизма». Хотя в ваших инструкциях по кодированию может быть сказано «используйте TPL здесь», если на хост-платформе нет необходимых ядер, она просто вызовет вместо них устаревший последовательный код.
Я начал использовать TPL во всех своих проектах. Особенно в любом месте, где есть циклы (это требует, чтобы я проектировал свои классы и методы таким образом, чтобы не было зависимостей между итерациями цикла). Но любое место, которое могло быть просто старым добрым многопоточным кодом, я просматриваю, чтобы посмотреть, могу ли я теперь разместить это на разных ядрах.
Моим любимым до сих пор было приложение, которое загружает ~ 7800 различных URL-адресов для анализа содержимого страниц, и если оно находит информацию, которую ищет, выполняет некоторую дополнительную обработку …. обычно на это уходило от 26 до 29 минут. Моя рабочая станция Dell T7500 с двумя четырехъядерными процессорами Xeon 3 ГГц, 24 ГБ оперативной памяти и 64-разрядной версией Windows 7 Ultimate теперь выполняет всю работу примерно за 5 минут. Огромная разница для меня.
У меня также есть механизм обмена сообщениями publish / subscribe, который я рефакторил, чтобы использовать преимущества TPL (особенно при передаче данных с сервера клиентам… у вас может быть 10 000 клиентских компьютеров, которые заявили о своей заинтересованности в определенных вещах, и как только это событие произойдет, мне нужно отправить данные на все из них). Я еще этого не сделал, но я ДЕЙСТВИТЕЛЬНО с НЕТЕРПЕНИЕМ жду результатов по этому вопросу.
Пища для размышлений …