Не все йогурты одинаково полезны

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

Более того, реализаций для CPU уже две на виндах: AMD-шная входит в состав ATI Catalyst (драйверов для видеокарты) и даже при отсутствии подходящей видеокарты эта часть драйверов поставится. Кроме того, Intel-овский OpenCL на днях перешел из стадии альфа в бету. На Linux, кстати, есть еще IBM-овский OpenCL для CPU, все руки не доходят его ощупать.

Берем AMD-шный пример BitonicSort из APP SDK 2.4 (это AMD-шный SDK для GPGPU) и запускаем, без перекомпиляции, прямо на всех имеющихся в машине девайсах и реализациях. Сортируем 16 млн. элементов. В порядке падения быстродействия:

  1. Intel OpenCL (процессор i7-2600k @4.5Ghz): 10.6 сек.
  2. NVidia OpenCL (GTX480, драйвер 270.61): 16.4 сек.
  3. AMD OpenCL (Radeon 5870, драйвер 11.4): 29.3 cек.
  4. AMD OpenCL на CPU (тот же самый): 415 сек.
Я подозреваю, что AMD-шный OpenCL в случае CPU просто процессор не опознал и сгенерировал код для 8086 или что-то вроде этого. Для CPU AMD Kernel Analyzer показывает нам невекторизованый код, т.е. процессор не опознался и что под него генерировать AMD не знает. На предыдущем процессоре (i7-920) такой разницы с интеловским OpenCL (тогда он был в первой альфе) не было. При этом, при исполнении на AMD-OpenCL процессор загружен где-то на четверть, а "под интелом" - на 100%

Прикол тут в другом: по формальному быстродействию горшки ранжируются в обратном порядке: у AMD бешеные 2 терафлопса на float (по пресс-релизу AMD: 2.7 TFLOP/s), у NVidia - раза в два поменьше (в районе 1.35 TFLOP/s если формально считать), у CPU же, даже если AVX посчитать как 16 операций на такт (две AVX-операции на такт) получается 16 x 4 ядра x 4.5 гигагерца = 288 GFLOP/s.

Понятно, что сортировка - дело такое, для потоков плохо предназначенное.

Чтобы два раза не вставать: большинство AMD-шных примеров на GTX480 работает быстрее (и лишь некоторые - незначительно медленнее), чем на HD5870. Несмотря на формальные попугаи, говорящие об обратном. Обратного, чтобы OpenCL-примеры NVidia работали бы быстрее на AMD, - не наблюдается.

Update: Помучал тот же пример на машине с i7-920 и GTX280. AMD OpenCL/CPU никуда не годится и там, увы. Может быть надо kernel как-то иначе писать. Что же касается реализаций Intel (CPU) и NVidia (GPU), то на этой паре железок и BitonicSort они работают практически одинаково по скорости.

Comments

CUDA на CPU тоже работает, кстати.

Ты о какой-то "не родной" реализации?

Эмулятор они покрантили не помню когда (в 4.0 точно нет, но в 3.2 тоже вроде уже не было). Но главное - без перекомпиляции уж точно не работает....

Забавно, что в очередной раз подтверждает мои дилетанские представления о полной ж-е с софтом в ATI/AMD (я не могу им простить линуксовские драйвера под убунту)

А как обстоят дела с атишными драйверами под бубунтой?

С точки зрения енд-юзера в прошлом релизе было совсем всё плохо.
То бишь свежая ATI/AMD карта Sapphire Radeon HD5830 толком опенсорсным драйвером не поддерживалась (2D ускорение вообще не работало, окошки отрисовывались так медленно, что было видно последовательность операций), и потому я решил скачать "фирменный" драйвер. На результат я уже сильно ругался по-английски -- то не работает, то весит объяву что "не нашла я поддерживаемую карту", но при этом всё ускоряется. Ужас, в общем :)

В результате продал ту карту и купил nVidia на замену. Всё работает :)

Ну у меня тоже НВИДЯШНЫЕ под Xubuntu(9.04, 9.10, 10.10 и 10.04 на ура ставились и сносились).

Под редхатом 5й энтерпрайзом с полпинка встали драйвера на HD3500 или из подобной серии. Только вот я под линух не люблю не "фирменные драйвера" - уж либо весовские, либо проприоритетные...

Проблема в том, что если взять сколь-нибудь свежую ATI/AMD карту, то начинается полная ж-а.
Ясно, что если 100% линукс то не надо брать свежее видео-железо :) Но у меня на той машине и винда и линукс, и хочется чтобы и шашечки и ехать :)
В общем это отдельная тема для беседы, не буду гадить в этот тред :))

Почему не надо брать свежее видеожелезо?

Linux для NVidia - ключевая платформа (для вычислений), драйвера выходят достаточно быстро. Насколько они хороши именно как видео - я не в курсе, впрочем.
Но этот самый 270.61 (релизный с CUDA 4.0) и для Linux тоже доступен.

Я имел в виду свежее железо от ATI.

С NVidia у меня под линуксами ещё ни разу проблем не было (тьфу тьфу тьфу).
Максимум -- пересоберёт себя само, без дополнительных выкрутасов.

В общем NVidia на следующие лет 10, после чего я снова попробую AMD-шную карту, и если оно снова начнёт брыкаться, то снова будет послано на три буквы :)

При таком подходе, если он станет массовым, через 10 лет не будет никакого ATI.

Кстати я вот думаю, что для большинства обычных применений (не супер-игры и не супер-вычисления) через пару лет мы все перейдем на графику, встроенную в CPU. Нормальному юзеру нужен быстрый видеодекодер + чуть-чуть акселерации 2D/3D и все.

В смысле? AMD уже перестала использовать марку ATI, это я по привычке их так зову :)

Для полного вымирания должна издохнуть вся AMD, или планы по скрещиванию ужа с ежом (в смысле встраивания GPU в процессор, что и Интел и АМД теперь делают) дожны стать ну супер как популярны убив идею отдельной карты, о чём ты как-раз написал :)

Свежие версии у Интела в принципе уже достаточно шустрые для "обычных" задач, вот только задачи всё растут. Скажем, ранние версии не тянули декодинг 1080p, или не было версии flash с хорошим ускорением, так что ютюб всякий исходил рваными кадрами со 100% загрузкой.

Я тоже по привычке. В том смысле, что отдельных видеокарт у них не будет - если с ними все так мучаются.

Что касается граф-ядра в процессоре, то лично я его попробовать не могу, чипсет не умеет (P67), но вроде декодирование видео там с какой-то феноменальной скоростью работает. Которое Quick Sync.

Ага, я хочу попробовать. Особенно после некоторых результатов декодирования граф-картой :)
До сих пор наивно думал что операции декодирования/кодирования -- однозначны вне зависимости от того через что декодируют. Оказалось ха-ха два раза :)

Конечно ха-ха. Во-первых, есть быстрые (но не очень точные) реализации sin/cos/log/exp, которые на разных архитектурах тем более будут разные.

Во-вторых, там запросто полезут всякие проблемы out of gamut (для ярких точек, скажем) c которыми кто-то разбирается, кто-то нет. Там же внутре небось YCC или что-то подобное (я не в курсе видео, но должно быть так), а выдать надо RGB.

Ну я понимаю когда открытым текстом говорят что вот есть точная реализация (но медленная), а вот вам приблизительная, но в N раз быстрее. Но тут оказалось что аппаратное ускорение это тяп-ляп со значением числа пи до четырёх :)

Я-то думал что при аппаратном ускорении стараются отоптимизировать под честный алгоритм (скажем, при распаковке JPG изображения с аппаратным ускорением я ожидаю, что оно совпадёт с программным, но будет быстрее благодаря спец-операциям, а не потому что там смухлевали и закидали всё примерными таблицами из ПЗУ)...
А тут оказывается что с использованием quick sync не только быстрее, но при этом ещё и точнее. Интрига :)

Я это место в деталях не знаю (да и не в деталях - только пользователь).

На NVidia выигрыш от аппаратных неточных sin/cos/exp/ln настолько большой (а точность там приемлемая, пока не начнешь их вычитать) что конечно фигачат ими.
Что там у интела - вообще не представляю. Вот сделают они DX11 (т.е. с DirectCompute) - можно будет посмотреть внимательнее.

Это не говоря о том, что можно вообще сделать sin/cos/whatever на текстурных лукапах (т.е. таблицей с аппаратной интерполяцией), будет еще быстрее.

Не, ну честно не распознали новый горшок, сгенерировали нечто под generic x86_x64, имеют право в первом приближении.

Насколько я понимаю они просто меняют периодически достаточно всего, после чего полгода линуксовый отдел пытается с этим всем новым взлететь, в то время как виндусятники как-то умудряются от версии к версии жить без особых ужасных крахов.
Хотя я может просто не видел сценария, когда родной ATIшный драйвер под винду внезапно теряет 2D ускорение :)

Для меня новость, что ай7 понимает опенЦЭЭЛ.
Но сортировка - это не совсем тривиальная задача.

Как быть с рассчётом очень большого числа матриц?

Я думаю, от задачи зависит.

Мне нетрудно любой из AMD-шных примеров с матрицами запустить таким же образом, собственно. Но я не уверен в их качестве, скажем нвидиевский пример умножения матриц из SDK (именно пример, не sgemm/dgemm из библиотеки cublas) - плохой.

Вот LU-разложение, 1024x1024, double. Тоже пример из SDK AMD, не знаю насколько хорош (но думаю что нинасколько)

GTX480 - 0.14 сек
HD 5870 - 0.32 сек
i7-2600@4.5, Intel OpenCL: 1.5 сек
i7 ..., AMD OpenCL: 13 сек.

При увеличении размера матрицы разрыв Nvidia/AMD сильно растет. Для матриц 2048x2048: 0.85 сек - NVidia, 7.5 сек ATI
4096: 6.39/41.2

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

А в i7-980 OpenCL ведь ещё быстрее должен быть?
Но разрыв колоссальный.

Не факт, что быстрее.

6 ядер вместо 4, разогнать можно, допустим, до тех же 4.5GHz, но в новом i7 - AVX и, соответственно, 8 float/4 double на операцию (таймингов не знаю, но допустим как и раньше две на такт), а в старом - только SSE4.2, вектор короче т.е. 4float/2double за раз.
А уж матричные операции векторизуются на раз.

Но сам пример, скорее всего, не вполне хорош и делать по нему выводы - неправильно. Производительность - не переносится.

"Понятно, что сортировка - дело такое, для потоков плохо предназначенное."

А почему, собственно? Можно разбить входные данные на N равных кучек по количеству процессоров, и сортировать независимо, потом сливать.

Или речь о том чтобы фреймворк сам догадался все это сделать?

Потому что SIMD. Т.е. если ветвление, один поток по одной ветке, а второй - по другой, то один поток стоит, а потом другой стоит.

А если сортировать чисто слиянием? Можно представить себе SIMD-инструкцию типа max(x,y) которая как бы и не ветвится?

Не проходит, да. Кроме min/max надо еще двигаться по спискам и там конечно без ветвления не обойтись.

А как без ветвления то? Вот у меня есть две "ленты" (их верхушки). Допустим я даже max произвел (на SSE такая операция есть, на видеокартах - скорее нету, но точно не знаю) и знаю какое значение поместить в выходной поток.

Но теперь мне надо на одной из лент продвинуть указатель. На какой?

Т.е. я даже могу, наверное, представить, что у меня номер ленты вычисляется, только вычисление адреса - это еще хуже, чем условный переход, конвейер собъется нахрен.

Ага, некоторые приложения на AMD быстрее, что отвечает формальным гигафлопсам.

Мало их, страшно далеки они от народа.