Pull to refresh
180
Дмитрий Конобрицкий@Akson87

Пользователь

44
Subscribers
Send message
Если данные по разу читаются, может их вообще не надо копировать? Пусть по PCIe потихоньку перетекают к GPU.
Есть несколько ответов на этот вопрос:
1) У меня нет ничего от AMD, так уж вышло и вряд ли изменится, а архитектуры таки у них разные,
2) Точно также Вы и сами в кавычки поставили,
3) Из тех утилит, которыми я пользовался для nVidia не попалось ничего, о чем можно было бы сказать, что этого достаточно.

Мне хочется видеть какая команда сколько каких ресурсов может потратить. Я просто хочу что-то наглядное. Пусть даже статическое, но под nVidia и удобное. Но это уже так… из серии чего бы хотелось…

Что реально нужно, так это дебагер (для Windows+nVidia+OpenCL)
Я всегда рад узнать, что я упустил или недопонял, так что буду рад услышать комментарии.

А про интересно… наверное соглашусь.
Хотя есть подозрение, что получение максимальной производительности на CPU — то еще веселье:). Просто обычно никто не парится, если неоптимальный код работает на сколько-то процентов медленнее, чем мог бы. А вот с GPU разница идет уже в разы и десятки раз, поэтому особого выбора и не остается, только писать оптимально, GPU плохой код не прощает:)
Похоже, что тут наши дороги расходятся:) (я про OpenCL и CUDA). OpenCL не имеет доступа к Cuda API и Driver API, что логично в целом, но является виной nVidia так как можно было бы сделать расширения. В результате, я не могу управлять размером кэша Fermi (всегда 16Кб L1) и очень Вам (CUDA программистам) завидую:). То же самое могу сказать про ядра, в OpenCL они компилируются во время выполнения и дальнейшая их судьба не контролируется (во всяком случае я не встречал ничего такого, хотя, честно говоря, не было нужды и не искал особо).
Для CUDA вроде есть, а вот для OpenCL не встречал. Если сделаете что-то юзабельное, да с возможностью отладки, цены Вам не будет:)
Я по возможности делаю свои ядра такими, чтобы на CPU запускались и компилировались студией, но всему есть свои пределы. Вообще, хотелось бы что-то простое, даже не симулятор, а утилитку, которая бы для каждой строки показывала сколько регистров съедено да сколько операций совершено, сколько запросов к памяти отправлено. Даже такая статистика бы пригодилась.
Копируется ли кернел или нет, зависит уже от конкретной реализации драйвера. Подозреваю, что какой-то механизм кэширования там есть, но это уже от нас скрыто, да и работает хорошо, поэтому лезть туда желания нет:)
Задержка маленькая… спору нет… пока не возникает желание запустить ядро много много тысяч раз:), как я и говорил обычно в районе 50-150мкс для моих ядер, что для 100 раз уже даст 5-15мс… с одной стороны, не очень много, а с другой не очень то и мало. У меня как раз на днях оказалось, что эта самая задержка кушала достаточное количество времени (ядра были очень очень простыми).
Похоже, что мы говорим о разных задержках. Я имел в виду ту, которая происходит при запуске ядра, которое уже скомпилировано и загружено. Т.е. если Вы запустите его 100 раз, Вы потратите 100хВремя задержки, при самом первом запуске задержка еще больше. А если в OpenCL Вы запускаете программу и компилируете ядро в самый самый первый раз, так там уже время измеряется в секундах. Правда потом драйвер уже скомпилированную программу берет из кэша и все происходит быстро. (не считая того, что в нвидевской реализации есть бага:), при изменении файлов, которые инклюдятся в основной файл, драйвер использует старую версию).
Вы совершенно правы, маленькое число потоков — это не всегда плохо. Ограничений бывает много. Все зависит от каждого конкретного алгоритма и его реализации. Только вот понимание всех возможных узких мест — не такая уж тривиальная задача. Вообще, хотелось бы какой-то упрощенный визуальный эмулятор GPU, где можно наглядно посмотреть как куда какие запросы улетают, где кто что ждет… но это из разряда фантастики:)

Только к примеру надо добавить, что если
read1
будет читать из разных участков памяти, то будет латентность 800*32, так как в результате будет куча запросов к памяти и целый warp будет ждать.

Спасибо за ссылку! Вроде не попадалась мне эта презентация, хотя подобным методом пользуюсь. Без экспериментов никуда:)
Я написал, что работал с GPU основанными на CUDA в самом начале, поэтому все ограничения идут от нее.
Для CPU все будет совсем иначе, но широкого использования CPU+OpenCL я пока не встречал, а из тех тестов, которые попадались, оно очень и очень сильно уступает SSE, так что пока драйвера не смогут делать OpenCL код сравнимый по скорости с SSE, смотреть в сторону OpenCL никто не будет. Cell'ы же штука весьма специфичная. Вот и остается только под GPU писать, хотя больше и не надо:)

Я не совсем понял Ваш комментарий к первому ограничению. То, что надо запускать много волокон — это понятно. Но проблема именно в том, что все вычисления выполняются по 32 волокна (warp). Если будет 1млн волокон, но каждое будет выполнять разные ветки — будет медленно.

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

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

Шестое ограничение есть везде, спору нет, только вот на GPU 63 регистра, а на CPU на несколько порядков больше. Как говорится, почувствуйте разницу. Могу предположить, что среднему программисту для реализации среднего алгоритма нужно количество регистров как раз между CPU и GPU, поэтому на CPU мы не задумываемся по этому поводу, а вот на GPU появляется дополнительная головная боль.

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

Про PCI-Express и проблему передачи, опять же, у Вас алгоритм/реализация, где все уперлось в эту шину, но это не всегда так. Часто один и тот же алгоритм (часто, но не всегда) можно реализовать по разному, где-то будет упираться в шину, где-то в память, где-то в процессорное время. Вот найти оптимальную реализацию — проблема. Причем варианты могут быть такие, что для CPU никогда бы и не подумал такое делать. Например считать в 4 раза больше данных, чем CPU, но сэкономить при этом на передачи данных и получить прирост производительности.
Спасибо!
Я попробую откладывать кучоки кода со значениями производительности, но не обещаю, что скоро соберется достаточно таких кусочков (в ближайшие месяца 2 пока не начну заниматься своим проектом), которые можно выложить в сети.
Не могу сказать точно, так как не знаю, что там внутри происходит в это время. Возножно и заполнение конвейера. Скорее всего там много чего происходит в это время. Могу сказать, что оно измеряется в десятках микросекунд (50-150) и не является постоянным.
Что касается книжек по GPGPU, то с ними все печально, есть пара популярных книжек от нвидии. Но, честно говоря, сильно много пользы они мне не принесли, там больше для совсем начинающих и про сам язык, простейшие вещи. Книжку о том, как надо думать чтобы все получилось я так и не нашел. Поэтому посоветовать ничего не могу кроме многократного перечитывания официальной документации по архитектуре на которой планируете все это запускать.

На счет правил все интересно, тут на целую книгу наберется:)
Из основного:
— Забудьте сразу про то, что оно может запускаться на разных архитектурах. Если выбрали Fermi, то все под него.
— GPU любит много ПРОСТЫХ потоков, если Вы не можете запустить 30к, до теоретического максимума не дойти.
— Сразу думайте о том, как вы будете читать ваши данные и храните соответственно.
— Латентность запуска ядра ~70микросекунд(не мс)
— Иерархические структуры = либо медленно либо убьетесь поддерживать и придумывать как их распараллелить
— На GPU много памяти, не надо ее экономить в ущерб производительности
— На GPU ядра очень простые и мало регистров.
— Главное — думайте заранее о том, как вы храните данные и, что вы с ними планируете делать. Все должно быть последовательно.
— И еще лучше запустить простой алгоритм 3 раза, чем сложный 1 раз.

Я попробую в следующем посте описать подробнее все это дело, сам сейчас думаю над архитектурой геометрической библиотеки под это дело… сильно и долго думаю, но тяжко это идет:)

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

Я в следующем посте напишу про то как традиционная оптимизация GPU кода может вредить производительности. Слишком уж много раз я на этом попадался… сидишь оптимизируешь, вот видно прямо, что меньше операций должно выполняться, а получается медленнее.
12 ...
30

Information

Rating
Does not participate
Location
Pittsburgh, Pennsylvania, США
Date of birth
Registered
Activity