Запуск одного экземпляра программы на каждое ядро ​​GPU на всех ядрах GPU одновременно - PullRequest
0 голосов
/ 10 марта 2019

У нас есть миллионы маленьких файлов для обработки некоторыми программами.

Точная программа не важна и изменяется также в зависимости от конкретной задачи.Однако это небольшие C ++ -программы, и у нас есть исходный код, но они не являются внутренне распараллеливаемыми.

Обработка одного небольшого файла занимает около 15 секунд при использовании одного среднего ядра ЦП (серия Intel i7).И это требует около 200 МБ ОЗУ во время работы программы.

Мы хотим распараллелить это на GPU и запустить на каждом ядре GPU (например, Cuda-core) один экземпляр программы.Таким образом, если у GPU 3000 ядер CUDA, то мы бы хотели запустить 3000 экземпляров параллельно.Если возможно, мы хотим использовать обычные рамки, такие как OpenCL (а не Cuda, но если для этого случая потребуется Cuda, который будет приемлемым).

Сейчас мы пытаемся оценить, возможно ли это (мыУ меня пока нет большого опыта в программировании GPGPU).Основная проблема, которую мы представляем, - это память.Если мы запустим, например, 3000 экземпляров параллельно, и каждому экземпляру потребуется 200 МБ видеопамяти, то нам потребуется 600 ГБ памяти.

Графические карты, которые мы имеем в виду в первую очередь, - это высокопроизводительные карты Geforce,которые обычно имеют от 8 до 11 ГБ памяти.И у нас есть графические рабочие станции с 4 картами на корпус / материнскую плату, которые мы сначала хотим использовать для этого (но позже, возможно, и в других системах с графическим процессором, поэтому мы предпочитаем общую среду, такую ​​как OpenCL).

Какие способыЕсть, чтобы решить эту проблему?

1 Ответ

4 голосов
/ 10 марта 2019

Точная программа не важна

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

Как правило, вы не сможете конвертировать всю программу C ++ 1: 1 вядро графического процессора, и даже если вам удастся это сделать, оно будет работать крайне плохо.Вам действительно нужно приложить усилия, чтобы переосмыслить вашу проблему с точки зрения операций типа SIMD, чтобы добраться куда угодно с графическими процессорами.

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

Память также является проблемой,но не только из-за общего объема VRAM, как вы указали, но и потому, что локальные переменные используют «личную» память, которая на самом деле является регистром и очень ограниченным ресурсом (в лучшем случае измеряется в килобайтах).

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

...