GPGPU против Multicore? - PullRequest
       36

GPGPU против Multicore?

35 голосов
/ 07 мая 2011

Каковы основные практические различия между GPGPU и обычным многоядерным / многопоточным программированием CPU с точки зрения программиста?В частности:

  • Какие типы проблем лучше подходят для обычной многоядерности, а какие типы лучше подходят для GPGPU?

  • В чем основные различияв модели программирования?

  • Каковы основные аппаратные различия, которые требуют каких-либо различий в модели программирования?

  • Какую из них обычно проще использоватьи на сколько?

  • Целесообразно ли в долгосрочной перспективе реализовать высокоуровневые библиотеки параллелизма для графического процессора, такие как параллельная библиотека задач Microsoft или std.parallelism ?

  • Если вычисления на GPU настолько впечатляюще эффективны, то почему ЦП не разработаны так же, как GPU?

Ответы [ 2 ]

38 голосов
/ 10 мая 2011

Интересный вопрос. Я исследовал эту проблему, поэтому мой ответ основан на некоторых ссылках и личном опыте.

Какие типы проблем лучше подходят для обычных многоядерных систем и какие типы лучше подходят для GPGPU?

Как упомянуто @Jared. GPGPU созданы для очень регулярных рабочих нагрузок, например, графики, плотного матрично-матричного умножения, простых фильтров фотошопа и т. Д. Они хорошо переносят большие задержки, потому что по своей природе они способны выдерживать выборку текстуры, операцию с циклом 1000+. Ядра GPU имеют много потоков: когда один поток запускает операцию с большой задержкой (скажем, доступ к памяти), этот поток переводится в спящий режим (а другие потоки продолжают работать) до тех пор, пока операция с длинной задержкой не завершится. Это позволяет графическим процессорам загружать свои исполнительные блоки намного больше, чем традиционные ядра.

Графические процессоры плохо справляются с ветвями, потому что графическим процессорам нравится группировать «потоки» (линии SIMD, если вы не nVidia) в деформации и отправлять их по конвейеру вместе, чтобы сэкономить на мощности выборки / декодирования команд. Если потоки сталкиваются с ветвью, они могут расходиться, например, 2 потока в деформации с 8 потоками могут брать ветвь, в то время как другие 6 могут не брать ее. Теперь деформацию нужно разделить на две деформации размером 2 и 6. Если ваше ядро ​​имеет 8 линий SIMD (именно поэтому оригинальная деформация сделала 8 нитей), теперь ваши две вновь сформированные деформации будут работать неэффективно. Деформация с 2 потоками будет работать с эффективностью 25%, а деформация с 6 потоками - с эффективностью 75%. Вы можете себе представить, что если графический процессор продолжает сталкиваться с вложенными ветвями, его эффективность становится очень низкой. Следовательно, графические процессоры плохо справляются с ветвями, и поэтому код с ветвями не должен выполняться на графических процессорах.

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

Следовательно, худший код для графического процессора - это код с меньшим параллелизмом или код с большим количеством ветвей или синхронизацией.

В чем основные различия в модели программирования?

Графические процессоры не поддерживают прерывания и исключения. Для меня это самая большая разница. Кроме того, CUDA не сильно отличается от C. Вы можете написать программу CUDA, в которой вы отправляете код в графический процессор и запускаете его там. Вы обращаетесь к памяти в CUDA немного по-другому, но опять же, это не принципиально для нашего обсуждения.

Каковы основные аппаратные различия, которые требуют каких-либо различий в модели программирования?

Я уже упоминал их. Самым большим из них является SIMD-природа графических процессоров, которая требует, чтобы код был написан очень регулярно, без ветвей и межпотоковой связи. Это часть того, почему, например, CUDA ограничивает количество вложенных веток в коде.

Какой из них, как правило, проще в использовании и на сколько?

Зависит от того, что вы кодируете и какова ваша цель.

Легко векторизованный код: процессор проще в кодировании, но низкая производительность. GPU немного сложнее в коде, но обеспечивает большую отдачу. Для всех остальных процессоры проще и зачастую также более производительны.

Целесообразно ли в долгосрочной перспективе реализовать высокоуровневые библиотеки параллелизма для графического процессора, такие как параллельная библиотека задач Microsoft или std.parallelism D?

Параллелизм задач по определению требует взаимодействия потоков, а также имеет ветви. Идея задач состоит в том, что разные потоки делают разные вещи. Графические процессоры предназначены для множества потоков, которые делают идентичные вещи. Я бы не стал создавать библиотеки параллелизма задач для графических процессоров.

Если вычисления на GPU настолько впечатляюще эффективны, почему ЦП не сконструированы так, как GPU?

Множество проблем в мире ветвисто и нерегулярно. 1000 примеров. Алгоритмы поиска графов, операционные системы, веб-браузеры и т. Д. Просто добавим - даже графика становится все более разветвленной и универсальной, как каждое поколение, поэтому графические процессоры будут все больше и больше походить на процессоры. Я не говорю, что они станут такими же, как процессоры, но они станут более программируемыми. Правильная модель находится где-то посередине между неэффективными центральными процессорами и очень специализированными графическими процессорами.

24 голосов
/ 07 мая 2011

Даже в многоядерном процессоре ваши рабочие единицы будут намного больше, чем в GPGPU. GPGPU подходят для задач, которые хорошо масштабируются, причем каждый кусок работы невероятно мал. GPGPU имеет гораздо большую задержку, потому что вам нужно переместить данные в систему памяти GPU, прежде чем к ним можно будет получить доступ. Однако, как только данные будут получены, ваша пропускная способность, если проблема масштабируется соответствующим образом, будет намного выше с GPGPU. По моему опыту, проблема программирования GPGPU заключается в задержке передачи данных из обычной памяти в GPGPU.

Кроме того, GPGPU ужасно взаимодействуют между рабочими процессами, если у рабочих процессов нет сферы локальной маршрутизации. Если вы пытаетесь общаться через GPGPU, вам будет очень больно. По этой причине стандартные библиотеки MPI плохо подходят для программирования GPGPU.

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

...