Про OpenCL-бенчмарки (опять, да!)

Злоба на эту тему у меня копится и периодически выплескивается.

История первая

В Mac OS X 10.8.3 поапгрейдили драйвера NVidia и у NVidia 6xx в LuxMark стало в полтора раза меньше попугаев.

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

  • Было (драйвер репортил): 28 юнитов
  • Стало: 7 юнитов (более широких, но не суть)
Само железо не изменилось. Мог, конечно, измениться (ухудшиться) OpenCL-компилятор, но у меня предположение другое: само приложение, увидев меньше юнитов, задает размеры грида (количество одновременно исполняемых Workgroups) поменьше. От этого происходит худшая утилизация железа (ну там латентность памяти не прячется) и уменьшаются попугаи. Проверить нетрудно, но лень читать исходники.

История вторая На Tomshardware большой тест скорости работы Titan GTX на вычислительных задачах.

Что мы видим:

  • На OpenCL-тестах: Titan в некоторых случаях хуже, чем 580GTX (и лишь незначительно лучше, чем 680GTX), а в некоторых - хуже 680GTX (у которой, заметим, поменьше юнитов и вообще всего поменьше при примерно той же архитектуре).
  • На CUDA-тестах: Titan всегда лучше всех, а вот второе место может быть как у 580GTX (двойная точность?), так и у 680GTX
CUDA - дает ожидаемые результаты (Titan ожидаемо быстрее всех), а с OpenCL - привычный бардак.

В очередной раз хочу сообщить, что тестировать один и тот же OpenCL-код на разном железе (без специфичных оптимизаций под конкретное железо) - бессмысленно.

Comments

>один и тот же OpenCL-код на разном железе (без специфичных оптимизаций под конкретное железо)

остаеться только собирать детали насчет что и куда лучше оптимизировать,
плюс использование Extension(s) ...

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

Ну так все логично - CUDA только для NVidia, OpenCL - для всех, а универсальное всегда проигрывает частному. Вот только с Titan совсем дурдом...

Если смотреть только на API, то OpenCL как-то не очень проигрывает Cuda, а наоборот, даже позволяет генерировать код на лету.
Другое дело как оно реализовано..

Мой поинт в том, что
а) общий OpenCL код действительно будет проигрывать, железо слишком разное и не оптимизировать под железо - нельзя (при этом, естественно, теряется куча преимуществ OpenCL)

б) Писатели бенчмарок - как мы видим на примере LuxMark - вообще не парятся. Т.е. вот с NVidia известно, что на старом железе (по Ферми) надо было держать ~192 треда на SM, чтобы попрятать global memory latency. Про Кеплер - не знаю, но как бы не ~1152 (SM вшестеро шире). Соответственно, ошибка в драйвере, когда он репортил больше юнитов, чем на самом деле было - приводила к повышению утилизации. И общему росту производительности.

Значит надо к бенчмарку относиться - что он не железо меряет, а "производительность OpenCL subsystem". Что в общем-то тоже разумно и имеет смысл, но попугаи получаются другой породы.

Да нет же ж.

Ну вот, к примеру, bank conflicts в Nvidia. Если код написан так, что на NVidia будут конфликты банков (а, к примеру, на AMD - не будет т.к. там все иначе) - то на NV будет жопа.
И что мы тестируем?

Получаем некоторое кол-во попугаев, которые не любят NVidia, вот и все.

Меня в этом плане больше bitcoin веселит: на 7970 - 550-800 попугаев, на 680 - 110-120. И вот что это - железо под задачу совсем не заточено и мы выкидываем этот бенчмарк, как "несправедливый", или все-таки бенчмарк о чем-то говорит, так как на реальной задаче AMD в 5 раз быстрее? Статистика - такая статистика...

С биткойном - надо разбираться в чем причина такой разницы.

Может быть железо не заточено (ну там у AMD есть битовые операции, к примеру, а у NV - нету).
А может быть просто реализация сделана левой ногой и можно в разы ускорить, просто никому не надо.

Ну то есть да, нет битовых инструкций в Fermi (и более старых)
А в Kepler - они появились.

Я вот это нагуглил: https://bitcointalk.org/index.php?topic=163750.0
330Mhash/sec - это, как я понимаю, примерно как один 7870

А, да, там в треде еще история, что вот если переписать на shared mem - то еще быстрее (в подробности не вдавался)

Ну, типа, да. Наверное :)

Ну все равно, маша - это маша, а два раза - это два раза. Причем маша - заточена под конкретное железо.

Ну да, под конкретное - потому что у более старого нету bit rotate.

О чем я и говорю: сравнивать код без hw-specific оптимизаций под конкретное железо - плохо. Сравнивать с оптимизациями - тоже плохо (по идеологическим причинам).

Т.е. понятно все, хочешь битмайнить - покупай AMD, это как раз не вопрос.

А вот если хочешь LuxMark-ать - скорее всего надо потратить время и довести их код до разумно работающего на NVidia, там я аппаратных особенностей как раз не вижу.

В ферми 192 нити необходимы для покрытия задержек арифметических операций. При отсутствии параллелизма на уровне инструкций.