Десять способов обмана на результатах измерения производительности GPU

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

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

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

Вы готовы увеличить производительность вашего графического ускорителя на бумаге без фактического увеличения производительности? Тогда читайте дальше …

1. Цитируйте результаты измерения производительности только для 32-битной арифметики с плавающей точкой, а не 64-битной.
Производительность GPU удваивается, если используется 32-битная точность. Наконец, кому нужно больше восьми десятичных разрядов? Само собой разумеется, что и версия кода для CPU, с которым вы сравниваете результаты, должно быть только 64-битной, так как, ну …, так люди пишут код для CPU (даже если производительность CPU также удваивается при использовании 32-битной арифметики) .

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

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

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

3. Цитируйте стоимость и распространенность дешевых GPU карт. Считайте производительность на лучшем оборудовании.
Вот готовый кусок текста, который вы можете адаптировать для своих нужд: «Графические процессоры являются важной платформой, на которую стоит ориентироваться, потому что они стоят до $ 100 и входят в стандартную комплектацию каждого современного компьютера. В нашем эксперименте мы измеряли производительность NVidia Tesla M2090 … ».

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

5. Отключите проверки корректности памяти (ECC).
Графические ускорители работают быстрее, обеспечивают более доступного объема памяти когда им не надо так сильно стараться обеспечить правильность данных. Кроме того, как какое-то из GPU ядер работает достаточно долго, чтобы это могло стать проблемой?

6. Сравнивайте производительность целого (или нескольких) GPU с одним CPU ядром.
Всегда сравнивайте то, с чего вы начинали (последовательная программа на CPU), с тем, что вы в конце (параллельная программа на GPU). Десятикратное ускорение GPU кода по сравнению с CPU кодом становится еще более впечатляющим, когда вы забываете сказать, что система имеет два сокета с восьмиядерными CPU, которые вы могли бы использовать вместо одного ядра.

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

8. Выбирайте размер задачи так, чтобы уместить его в память GPU.
Эта рекомендация работает в обоих направлениях. Если ваш GPU имеет 6 ГБ встроенной памяти, а размер данных вашей программы больше — уменьшите их до 6 ГБ и вы избавитесь всех расходов на синхронизацию и беспорядочную двойную буферизацию, которые влекут за собой большие размеры задач. Если ваш GPU имеет 6 ГБ встроенной памяти, а размер данных вашей задачи значительно меньше — тогда увеличьте размер данных, несмотря на разумные пределы. Так вы сможете получить преимущества дополнительной производительности от увеличенного параллелизма данных. Следующая рекомендация развивает эту точку зрения:

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

10. Выбирайте алгоритмы, лучше выполняются на GPU.
Лучшие CPU алгоритмы часто не являются лучшими на GPU и наоборот. Итак, вы должны всегда выбирать из всех алгоритмов тот, который имеет лучшие результаты на GPU, и сравнивать его с CPU версией. Что хорошего в этом подходе, в отличие от сравнения лучшего GPU и CPU алгоритмов, это то, что сравнение получается «честным». Наконец, вы запустили один и тот же алгоритм на обеих системах. Честно, правда?

Мысли напоследок

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

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