Когда я должен разгружать работу на GPU вместо CPU?

15

Новые системы, такие как OpenCL, создаются для того, чтобы мы могли запускать все больше и больше кода на наших графических процессорах, что имеет смысл, потому что мы должны быть в состоянии использовать как можно больше энергии в наших системах.

Однако со всеми этими новыми системами кажется, что GPU лучше, чем CPU во всех отношениях . Поскольку графические процессоры могут выполнять параллельные вычисления, многоядерные графические процессоры на самом деле кажутся намного лучше, чем многоядерные процессоры; Вы могли бы сделать много расчетов одновременно и реально улучшить скорость. Есть ли еще определенные случаи, когда последовательная обработка все еще лучше, быстрее и / или более эффективна, чем параллельная?

RétroX
источник
6
Не совсем вопрос про аппаратное обеспечение. Следует перефразировать слова «когда программирование процессора (ов) лучше, чем программирование графического процессора (ов)», и это довольно хороший вопрос IMO. Смотрите тег GPGPU среди других на SO. Но вопросы архитектуры "Какую технологию использовать" здесь лучше, чем там.
Кейт Грегори
1
@Kate Этот угол, кажется, очень хорошо освещен в связанном вопросе о супер-пользователе. Прочитав его, я немного удивлен, если честно, его сюда не перенесли. Там также это на SO. Я снова открою вопрос (так как вы правы, здесь есть вопросы по программированию). Я надеюсь, что мы увидим ответ, который не просто указывает на существующий (превосходный) охват этой проблемы.
Адам Лир
1
К слову, Анна, я думаю, что ответы должны быть гораздо больше о том, когда программист должен использовать графический процессор, а не чисто теоретическое обсуждение разницы между графическим процессором и процессором. Я отредактировал название, чтобы отразить это.
2
@RetroX Мы не можем закрывать вопросы как дубликаты, если они находятся на разных сайтах.
Адам Лир

Ответы:

26

Однако со всеми этими новыми системами кажется, что GPU лучше, чем CPU во всех отношениях.

Это фундаментальное неправильное понимание. Существующие ядра GPU по-прежнему ограничены по сравнению с текущими процессорами верхнего уровня. Я думаю, что архитектура NVIDIA Fermi является самым мощным из доступных графических процессоров. Он имеет только 32-разрядные регистры для целочисленной арифметики и меньше возможностей для предсказания ветвлений и спекулятивного выполнения, чем текущий стандартный процессор Intel. Чипы Intel i7 обеспечивают три уровня кэширования, ядра Fermi - только два, и каждый кэш на Fermi меньше, чем соответствующий кэш на i7. Межпроцессное взаимодействие между ядрами графического процессора довольно ограничено, и ваши расчеты должны быть структурированы, чтобы учесть это ограничение (ядра объединены в блоки, а связь между ядрами в блоке относительно быстрая, но связь между блоками медленная).

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

Процессоры на GPU живут в изолированном мире. Они могут управлять дисплеем, но у них нет доступа к диску, сети или клавиатуре.

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

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

Чарльз Э. Грант
источник
Поддержка двойной точности является частью Shader Model 5, и у AMD / ATI она есть.
Бен Фойгт
@ Бен, спасибо за исправление. Я удалил неправильное утверждение.
Чарльз Грант
11

GPU не универсальные процессоры, как процессоры. Они специализируются на выполнении одной очень конкретной вещи - применяют один и тот же код к большому количеству данных - и делают это очень, очень хорошо, намного лучше, чем процессор. Но в большинстве приложений речь идет не о применении одного и того же кода к большому объему данных; речь идет о цикле событий: ожидание ввода, чтение ввода, его обработка, а затем ожидание дополнительного ввода. Это довольно последовательный процесс, и графические процессоры сосут на «последовательном».

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

Этот вопрос помечен как «оптимизация», поэтому не забывайте относиться к нему как к одному. Применяйте оптимизацию GPU, когда тестирование и профилирование показывают, что оптимизация необходима, и характер задачи таков, что можно применять оптимизацию GPU. В противном случае не беспокойтесь об этом, так как это будет преждевременной или неправильной оптимизацией, которая вызовет больше проблем, чем исправит.

Мейсон Уилер
источник
8

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

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

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

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

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

  1. Проблема настолько параллельна, что вы можете ожидать большой выгоды от минимальных усилий, или
  2. Прирост скорости настолько важен, что оправдывает много дополнительной работы.

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

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

Джерри Гроб
источник
3

Вы могли бы сделать много расчетов одновременно и реально улучшить скорость.

улучшить скорость? Ну и что? В течение прошлого года я могу вспомнить только один или два раза, когда это было необходимо. Большую часть времени меня просили изменить или исправить логику, приспособиться к другому источнику данных, улучшить взаимодействие с пользователем и т. Д. И т. Д. Единственная скорость, которую клиенты интересовали в этих случаях, - это скорость внесения изменений. «Пожалуйста, выпустите новую функцию через месяц, а еще лучше - через две недели».

Не поймите меня неправильно - мне как программисту нравится сжимать такты процессора. Просто это искусство обычно не пользуется большим спросом.

Есть ли еще определенные случаи, когда последовательная обработка все еще лучше, быстрее и / или более эффективна, чем параллельная?

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

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

комар
источник
2

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

quant_dev
источник
3
Можете ли вы рассказать немного подробнее? Вы предоставили три заявления без информации или объяснений относительно их правдивости.
Что ж, отсутствие эффективных вычислений с двойной точностью общеизвестно: en.wikipedia.org/wiki/GPGPU
quant_dev
@quant: Ваша информация устарела как минимум на 2 года: 544 GigaFLOPS намного быстрее любого основного процессора.
Бен Фойгт
@Ben Я не вижу, где ваша ссылка упоминает производительность с двойной точностью.
Quant_dev
@quant: awurl.com/Tt7LAX8lH
Бен Фойгт
2

Простое правило: если то, что вы делаете, может быть сформулировано в терминах конструкций из линейной алгебры и критично ко времени, делайте это на GPU, иначе используйте CPU.

Графические процессоры не похожи на большое количество процессоров, они имеют совершенно разные характеристики производительности.

dan_waterworth
источник
Если это "критично ко времени", у вас, вероятно, нет времени на перенастройку графического процессора для вычислительного шейдера и загрузку данных. Это большие проблемы, которые приносят наибольшую пользу.
Бен Фойгт
@Ben, я думаю, что у нас есть разные определения «критических по времени», я имею в виду, что вычисления находятся на критическом пути в течение значительного периода времени.
dan_waterworth
1

Если вам нужно грубое вычисление чисел, лучше всего использовать графические процессоры. Тем не менее, все эти ALU означают, что имеется меньше транзисторов, предназначенных для схем управления потоком (ветвления). Итак, если вам нужно написать что-то, что требует много сложного потока управления, много условных выражений и т. Д., То процессор будет быстрее.

Alex
источник