Есть ли какие-либо преимущества в использовании процессора вместо графического процессора?

63

Я исследовал процессоры и видеокарты и обнаружил, что графические процессоры работают намного быстрее, чем процессоры. Я читал в этой статье , что 2-летний графический процессор Nvidia превзошел процессор Core I7 Intel с частотой 3,2 ГГц в 14 раз при определенных обстоятельствах. Если GPU такие быстрые, почему разработчики не используют их для каждой функции в игре? Возможно ли для графических процессоров делать что-либо кроме графики?

Даниэль Пендергаст
источник
17
Если вы находитесь в игре, в которой вы разгружаете все на GPU, а ваш процессор почти ничего не делает, то вы можете повысить производительность, перенеся часть нагрузки на процессор.
Тетрад
3
ваш графический процессор может быть лучше вашего центрального процессора, но я не думаю, что ваша видеокарта лучше вашей материнской платы (и я не буду сравнивать ОС с драйвером)
e-MEE
27
GPU is faster than a CPUэто ложный миф, в который многие верят, увидев тесты, основанные на проблемах, специально предназначенных для GPU (этот класс проблем называется «смущающе параллельными проблемами»), см. мой ответ на этот вопрос SuperUser: почему мы до сих пор используем Процессоры вместо графических процессоров?
Ли Райан
5
Одним из преимуществ является то, что каждый компьютер имеет процессор :)
Тим Холт

Ответы:

50

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

Программа, выполняемая в графическом процессоре, имеет смысл, когда она должна выполняться много раз параллельно, например, когда вам нужно смешать все пиксели из текстуры A с пикселями из текстуры B и поместить их все в текстуру C. Эта задача, когда выполняется в процессор, будет обрабатываться как-то так:

for( int i =0; i< nPixelCount; i++ )
     TexC[i] = TexA[i] + TexB[i];

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

     TexC[i] = TexA[i] + TexB[i];

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

Этот способ работы подходит для тех случаев, когда вам приходится обрабатывать очень много небольших входных данных, но на самом деле это плохо, когда вам нужно создать программу, которая может иметь условное ветвление. Итак, теперь давайте посмотрим, что делает процессор, когда дело доходит до некоторой проверки состояния:

  • 1: выполнить программу до первой логической операции
  • 2: оценить
  • 3: Продолжить выполнение из адреса памяти результата сравнения (как с инструкцией asm JNZ)

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

  • 1: Сделайте версию программы, которая следует только за ветвью A, заполните этот код во всех ядрах.
  • 2: выполнить программу до первой логической операции
  • 3: Оценить все элементы
  • 4: Продолжить обработку всех элементов, которые следуют за веткой A, поставить в очередь все процессы, которые выбрали путь B (для которого нет программы в ядре!). Теперь все те ядра, которые выбрали путь B, будут бездействовать !! - наихудший случай - выполнение одного ядра и ожидание любого другого ядра.
  • 5: Как только все As закончили обработку, активируйте версию программы ветви B (скопировав ее из буферов памяти в небольшую память ядра).
  • 6: Выполнить ветку B.
  • 7: при необходимости смешать / объединить оба результата.

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

Тогда, конечно же, существует проблема того, что другие архитектуры так хорошо справляются с задачей логических операций, гораздо дешевле и надежнее, стандартизированы, лучше известны, энергоэффективны и т. Д. Более новые видеокарты вряд ли совместимы со старыми без эмуляции программного обеспечения, они использовать разные ассемблерные инструкции между ними, даже если они принадлежат одному и тому же производителю, и что в настоящее время большинству компьютерных приложений не требуется этот тип параллельной архитектуры, и даже если они им понадобятся, они могут использовать стандартные API, такие как OpenCL, как упомянутый eBusiness, или через графический интерфейс API. Возможно, через несколько десятилетий у нас появятся графические процессоры, которые смогут заменить процессоры, но я не думаю, что это произойдет в ближайшее время.

Я рекомендую документацию от AMD APP, которая многое объясняет об их архитектуре GPU, и я также видел о NVIDIA в руководствах по CUDA, которые мне очень помогли в понимании этого. Я до сих пор не понимаю некоторые вещи, и я могу ошибаться, возможно, кто-то, кто знает больше, может подтвердить или опровергнуть мои заявления, что было бы здорово для всех нас.

Пабло Ариэль
источник
6
странная аналогия, но это хороший момент the fastest isn't always the fastest.
Ли Райан
1
Спасибо! Я думаю, что это интересная тема, потому что она связывает многие концепции программирования игр с тем, как работает аппаратное обеспечение, что несколько забыто на земле современных языков высокого уровня. Я хотел бы добавить еще кое-что, но написание ответа заняло уже некоторое время, поэтому я постараюсь обновить его позже, например, возможности ЦП в «защищенном режиме», скорость шины памяти и т. Д., Но я надеюсь, что это уточнить некоторые технические недостатки выполнения всего в GPU.
Пабло Ариэль
6
Аналогия была бы намного лучше, если бы она была точной. Автомобили F1 обладают огромными тормозными способностями, которые позволяют им поддерживать высокую скорость дальше по кривой, вместо того, чтобы начинать тормозить заранее. Повороты на высокой скорости также лучше благодаря высоким прижимным силам, хотя радиус поворота, вероятно, не подходит для парковок. Более вероятные причины могут включать в себя нехватку места для хранения, зеркало заднего вида, кондиционер, круиз-контроль, защиту от элементов, пассажирских сидений, подвеску и дорожный просвет для работы на плохих дорогах, а также различные другие вещи, распространенные в пассажирских транспортных средствах.
GargantuChet
5
@Pablo Ariel Я отвечаю на утверждение: «Автомобили F1 не могут сломаться или повернуть так быстро, как это делают большинство машин». Вы предполагаете, что машины F1 могут ускоряться только по прямой, и не очень хороши в поворотах или при замедлении. Но машины F1 на самом деле могут тормозить намного быстрее, чем «большинство машин», и превосходны на скоростных поворотах.
GargantuChet
4
Аналогия будет более точной, если вы будете думать о Драгстере, а не о машинах Формулы 1
Агустин Мерилес
32

Графические процессоры очень хороши в параллельных задачах. Что здорово ... если вы выполняете параллельные задачи.

Игры - это наименее распараллеливаемое приложение. Подумайте о главном игровом цикле. ИИ (предположим, что игрок рассматривается как особый случай ИИ) должен реагировать на столкновения, обнаруженные физикой. Следовательно, он должен работать позже. Или, по крайней мере, физика должна вызывать подпрограммы ИИ в пределах границ физической системы (что, как правило, не очень хорошая идея по многим причинам). Графика не может работать, пока не закончилась физика, потому что физика - это то, что обновляет положение объектов. Конечно, ИИ должен запускаться и перед рендерингом, так как ИИ может порождать новые объекты. Звуки должны идти после ИИ и контроля игрока

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

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

Итак, вы смотрите на 4 потока: игра, графика, звук и, возможно, длительная обработка ИИ. Это не так много. И это не почти достаточно для графических процессоров, которые могут иметь буквально сотни потоков в полете сразу. Это то, что дает графическим процессорам их производительность: возможность использовать все эти потоки одновременно. И игры просто не могут этого сделать.

Теперь, возможно, вы сможете пойти «широко» для некоторых операций. ИИ, например, обычно не зависят друг от друга. Таким образом, вы можете обрабатывать несколько десятков ИИ одновременно. Вплоть до того момента, когда вам действительно понадобится сделать их зависимыми друг от друга. Тогда у тебя проблемы. Физические объекты также независимы ... если только между ними нет ограничений и / или они не сталкиваются с чем-то. Тогда они становятся очень зависимыми.

Плюс, есть тот факт, что у GPU просто нет доступа к пользовательскому вводу, что, как я понимаю, очень важно для игр. Так что это должно быть обеспечено. Он также не имеет прямого доступа к файлу или какого-либо реального способа общения с ОС; Итак, еще раз, должен быть какой-то способ обеспечить это. Ох, и все это обработка звука? Графические процессоры не издают звуков. Таким образом, они должны вернуться к процессору, а затем к звуковому чипу.

Да, и кодирование для графических процессоров это ужасно. Трудно сделать правильный выбор, и то, что является «правильным» для одной архитектуры GPU, может быть очень, очень неправильным для другой. И это даже не просто переход с AMD на NVIDIA; это может быть переключение с GeForce 250 на GeForce 450. Это изменение в базовой архитектуре. И это может легко сделать ваш код не очень хорошо работает. C ++ и даже C не допускаются; лучшее, что вы получите, это OpenCL, который похож на C, но без каких-либо тонкостей. Как рекурсия . Это верно: нет рекурсии на графических процессорах.

Отладка? О, я надеюсь, что вам не нравятся функции отладки вашей IDE, потому что они, безусловно, не будут доступны. Даже если вы используете GDB, поцелуй на прощание. Вам придется прибегнуть к printfотладке ... подождите, printfна GPU их нет. Таким образом, вам придется записывать в ячейки памяти, и ваша программа-заглушка процессора будет читать их обратно.

Правильно: ручная отладка. Удачи с этим.

Кроме того, эти полезные библиотеки вы используете в C / C ++? Или, возможно, вы скорее парень .NET, используете XNA и так далее. Или что угодно. Это не имеет значения, так как вы не можете использовать любой из них на GPU. Вы должны кодировать все с нуля. И если у вас уже есть кодовая база, то настало время переписать весь этот код.

Так что да. Это ужасно на самом деле для любой сложной игры. И это даже не сработает, потому что игры просто не параллельны, чтобы помочь.

Николь Болас
источник
21

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

Я подозреваю, что разработчики не делают этого по ряду причин, в том числе:

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

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

  • Графический процессор обычно не имеет доступа к таким ресурсам, как сетевые карты, клавиатуры, мыши и джойстики, поэтому он все равно не может обрабатывать все аспекты игры.

В ответ на вторую часть вашего вопроса: да, есть и другие варианты использования. Например, проекты, такие как SETI @ Home (и, возможно, другие проекты BOINC), используют графические процессоры (такие как nVidia) для высокоскоростных сложных вычислений:

  Запустите SETI @ home на своем графическом процессоре NVIDIA
  http://setiathome.berkeley.edu/cuda.php

( Мне нравится ваш вопрос, потому что он представляет интересную идею. )

Рэндольф Ричардсон
источник
18

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

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

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

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

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

AAAAAAAAAAAA
источник
6

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

Использовать ЦП с одним потоком легко, многопотоковое использование сложнее, использовать много компьютеров с параллельной библиотекой, так как PVM или MPI сложно, а использовать GPU сложнее всего.

Эллис
источник
4

Кроме того, на что ответил Рэндольф Ричардсон, есть некоторые определенные функции, которые процессоры GPU не могут обрабатывать сами. Например, некоторые команды управления графической памятью обрабатываются ЦПУ, поскольку графический процессор не может их обработать.

И есть еще одна важная причина: графический процессор предназначен для многопоточных вычислений. Это означает, что производители графических процессоров могут легко добавлять ядра, когда хотят увеличить вычислительную мощность. Но есть много задач, которые нельзя разделить на более мелкие задачи, такие как вычисление n-го числа в ряду Фибоначчи . В этих ситуациях процессор намного быстрее, так как он более оптимизирован для однопоточных задач.

Ali1S232
источник
4

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

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

Kylotan
источник
Аналогия с самолетом очень хорошая (+1), но в отношении процессоров, поддерживающих разные типы данных, это на самом деле более языковая концепция более высокого уровня, поскольку процессоры (по крайней мере, в пространстве Intel), как правило, имеют дело только с данные в самых основных формах (например, биты, байты, слова, слова и т. д.). Существуют некоторые инструкции по замкнутому циклу для сканирования или копирования данных, которые заканчиваются нулевым байтом, но данные в этих случаях на самом деле не распознаются ЦП как определенный тип (за исключением того, что они являются нулевыми оконечными порциями данных). в контексте этих петель).
Рэндольф Ричардсон
@Randolf: ЦП имеют разные инструкции и регистры, которые работают с разными типами данных низкого уровня (например, со знаком и без знака, с целым числом и с плавающей запятой). Это относится к 8086 и даже к большинству современных архитектур, и это не совсем бесплатно.
Kylotan
Я уверен, что они все еще выполняют много линейной обработки в базовой архитектуре. Со стороны программирования требуется только инструкция для графического процессора, но ядра не работают точно параллельно из-за их зависимости от другого оборудования, которое не является параллельным, например, чтение из памяти, возможно, графический процессор может предоставлять данные одному ядру в время.
Пабло Ариэль
3

Разработчики этого используют графические процессоры для всех функций , они хорошо. Они используют процессоры для всех функций, в которых они хороши. Что заставляет вас думать, что они не делают?

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

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

Дэвид Шварц
источник
1

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

Максимус Минимус
источник
0

Это старая ветка, но эта недавно опубликованная статья может ответить на этот вопрос. В этом документе, опубликованном в ACM Computing Surveys 2015, показано, что каждый из процессоров и графических процессоров имеет свои уникальные преимущества, и, следовательно, в этом документе обосновывается переход от парадигмы «CPU v GPU» к парадигме «совместные вычисления CPU-GPU».

Обзор методов гетерогенных вычислений CPU-GPU

user984260
источник