При программировании, возможно ли, чтобы загрузка процессора и графического процессора составляла 100%?


43

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

Поэтому я задался вопросом: неизбежно ли использование графического процессора при 100% -ной загрузке, а загрузка процессора (например, на 50%)?

Или, точнее: могут ли некоторые вычисления, которые обычно выполняются графическим процессором, выполняться процессором, если первый из них загружен на 100%, так что оба достигают нагрузки на 100%?

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


53
Тривиально возможно, чтобы и CPU, и GPU выполняли бесконечный цикл NO-OPs одновременно, что приведет к загрузке обоих на 100%.
Йорг Миттаг

17
Следуя точке зрения @ Jörg, единственное, что измеряется% CPU, это то, какая доля времени не тратится на ожидание других процессоров. 100% может быть хорошо, если программа эффективна, или плохо, если программа неэффективна. Слишком часто люди сосредотачиваются на CPU%, как если бы это был показатель производительности - это не так.
Майк Данлавей

22
Оригинальный Crysis сделал это просто отлично.
CubicleSoft

5
@MikeDunlavey, ты поднял хорошую мысль. С автомобилями мы не измеряем их производительность по оборотам, мы измеряем скорость.
Капитан Мэн

1
@ JörgWMittag: Процессор, может быть. Но ОС и графические процессоры имеют решающие проблемы, чтобы справиться с бесконечными циклами. А именно, если шейдер не завершает работу в течение разумного промежутка времени, он умирает и графический процессор сбрасывается.
Николь Болас

Ответы:


62

Теоретически да, но практически это того не стоит.

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

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

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


1
Вы упомянули, что с большинством проблем разница в производительности между реализациями CPU и GPU огромна , я на самом деле весьма заинтересован в том, в какой степени разница в производительности. Будут ли у вас какие-либо цифры или статьи об этом (например, на примере текстурного 3D-рендеринга)? Спасибо за ваш ответ и за ваше время!
MadWard

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

3
@gardenhead Ничто во вселенной не поддерживает неограниченную рекурсию, потому что вселенная имеет конечный размер и конечную плотность информации. «Тьюринг-полнота» системы - это, как правило, обсуждение того, что было бы возможно при устранении таких ограничений.
Random832

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

7
@leftaroundabout Современные графические процессоры тривиально завершены, как и любой процессор . Полнота Тьюринга не имеет ничего общего с: 1) производительностью 2) читабельностью исходного кода. Процессоры 80-х были так же близки к TC, что и все остальное: либо TC, либо нет (последний вариант - чепуха).
Маргарет Блум

36

Это не связано с программированием игр. Некоторый научный код также может использовать как графический процессор, так и процессор.

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

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

Узнайте больше о гетерогенных вычислениях .

См. Также OpenACC , поддерживаемый последними версиями GCC (например, GCC 6 в июне 2016 г.)


1
Вы правы, мои теги и заголовки вводили в заблуждение, убирали игры и добавляли производительность / оптимизацию. Я не имел в виду, что это было исключительно для игр, но именно здесь я это заметил. Я думал, что это тоже должно быть очень специфично для оборудования. Спасибо за ваш ответ и ссылки!
MadWard

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

11

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

Если вы получаете 100% загрузку ЦП, это не обязательно означает, что вы получаете всю производительность системы. Процессоры часто могут делать несколько разных вещей одновременно, скажем, деление и сложение. Если вы можете начать разделение рано, оно может быть перекрыто дополнением. Ваш настольный ЦП, скорее всего, имеет неработающий модуль, который будет переупорядочивать операторы, чтобы извлечь выгоду из таких совпадений. Или если у вас есть следующая программа:

if (expr1)
    expr2;
else
    expr3;

Процессор переупорядочения попытается вычислить три выражения одновременно, а затем отбросит результат одного из них. Это делает это быстрее в целом. Если в вашей программе есть какой-то блокировщик, и вы не можете изменить порядок, то вы используете меньше дорожек в ЦП, но, вероятно, он все равно будет показывать 100%.

Тогда у вас есть SIMD-функции в процессорах, которые являются векторными операциями. Это похоже на GPGPU-light в том смысле, что вы обычно выполняете только четыре или восемь операций одновременно, а графические процессоры - 32 или 64. Тем не менее, вы должны использовать это для запуска FLOPS.

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

Я немного программировал на машине IBM Blue Gene / Q. Он имеет много уровней иерархии ( схема устаревшего Blue Gene / L ) и, следовательно, его трудно программировать эффективно. Вам придется использовать полную иерархию вплоть до SIMD и SMT (Intel называет это HyperThreading), чтобы добиться максимальной производительности.

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

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


1

Возможно, вас заинтересует движок браузера Servo , разрабатываемый в Mozilla Research, а точнее его Web Render (видео) .

Хотя динамическое переключение задачи с CPU на GPU может быть нецелесообразным, как упоминалось в других ответах (в частности, @ Philip's), может оказаться целесообразным заранее изучить нагрузку на CPU / GPU для типичных рабочих нагрузок и переключить некоторые задачи на менее загруженные в целом задачи. один.

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

Первоначальная версия Web Render оказалась весьма успешной в повышении производительности, но не пыталась решить проблему рендеринга текста (и имела несколько других ограничений). В настоящее время Mozilla Research работает над второй версией, которая должна иметь меньше ограничений и, в частности, поддерживать рендеринг текста.

Цель, конечно же, состоит в том, чтобы как можно больше разгрузить процесс рендеринга в графический процессор, оставив центральному процессору возможность свободно выполнять Javascript, обновлять DOM и все другие задачи.

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


0

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

В этой ситуации вы можете сделать это либо на ЦП и загрузить результаты в графический процессор для рендеринга, либо выполнить расчет и рендеринг на графическом процессоре. Я полагаю, что в настоящее время это делается на графическом процессоре (известном как «аппаратное скинирование»): это имеет смысл сделать, учитывая, что у вас есть относительно простые вычисления, которые должны быть выполнены тысячи раз, и каждая вершина может быть вычислена одновременно, так как результат вершины A не имеет отношения к результату вершины B.

Теоретически, однако, вы можете динамически переключаться между выполнением этого на CPU или GPU в зависимости от того, насколько перегружены GPU и CPU.

Однако основным препятствием для выполнения всех вычислений является то, что ЦП и ГП имеют разные сильные и слабые стороны. Массивно параллельные задания лучше выполняются на GPU, а интенсивные линейные задачи с ветвлением лучше выполняются на CPU. Только несколько заданий реально могут быть выполнены на обоих без серьезного снижения производительности.

В целом, основная проблема в программировании на GPU (по крайней мере, для OpenGL и DirectX 11 и ниже) заключается в том, что у вас мало контроля над тем, как GPU интерпретирует код вашего шейдера. Ветвление внутри шейдера рискованно, потому что, если вы случайно создадите зависимость между вычислениями, тогда графический процессор может решить начать рендеринг ваших пикселей один за другим, мгновенно поворачивая скорость 60 к / с до 10 к / с, несмотря на то, что фактические данные должны быть идентичны.


0

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

LuxRender использует OpenCL для облегчения этого, хотя сборки без OpenCL также существуют.

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


какой смысл показывать это изображение, какое отношение оно имеет к задаваемому вопросу?
комара

1
Эхх хорошо. Я удалю это. Я думал, что это легко продемонстрирует, что это за программное обеспечение. Но, возможно, это просто отвлекает. (Существует много различных видов движков рендеринга; этот ориентирован на фотореалистичные кадры.)
PythonNut

0

Да, это возможно.

Любые вычисления, которые может выполнять ЦП, могут делать и графические процессоры, и наоборот.

Но это необычно, потому что:

  • Сложность разработки Хотя один и тот же код можно запускать на процессоре и графическом процессоре (например, CUDA), процессоры обладают различными возможностями и характеристиками производительности. Одним из них является MIMD; другой, SIMD. То, что быстро на одном, медленнее на другом (например, ветвление), поэтому вам необходимо написать отдельный код, чтобы максимизировать производительность.

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

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.