Переносимость и оптимизация OpenCL между графическими картами Radeon

Я планирую погрузиться в OpenCL и читал (только поверхностные знания) о возможностях OpenCL, но у меня есть несколько вопросов.

Допустим, у меня есть AMD Radeon 7750, и у меня есть другой компьютер с AMD Radeon 5870, и я не планирую использовать компьютер с картой Nvidia. Я слышал, что оптимизация кода для конкретного устройства дает преимущества в производительности. Что именно означает оптимизация? Судя по тому, что я читал и немного догадывался, похоже, что это означает написание кода так, как нравится графическому процессору (как правило, не беспокоясь о том, что это карта AMD или Nvidia), а также способом, который соответствует тому, как графическая карта обрабатывает память (я предполагаю, что это зависит от вычислительного устройства? Или это зависит только от бренда?).

Итак, если я напишу код и оптимизирую его для Radeon 7750, смогу ли я перенести этот код на другой компьютер с Radeon 5870 и, без изменения какой-либо части кода, по-прежнему сохранять разумное количество преимуществ производительности от оптимизации ? В случае, если код не работает, будет ли изменение частей кода незначительной проблемой или это будет связано с переписыванием достаточного количества кода, поэтому было бы лучше сначала написать оптимизированный код для Radeon 5870 .


person user1604449    schedule 19.09.2012    source источник


Ответы (1)


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

Radeon 7750 имеет новый дизайн Graphics Core Next, а HD5780 основан на более ранней VLIW5 (RV770 ) Архитектура.

Чтобы ваш код хорошо работал на оборудовании HD5780, вы должны как можно интенсивнее использовать упакованные примитивные типы данных, особенно типы int4, float4. Это связано с тем, что компилятору OpenCL сложно автоматически обнаруживать параллелизм и упаковывать данные в широкие векторы. Если вы можете структурировать свой код так, чтобы вы уже приняли это во внимание, тогда вы сможете заполнить больше слотов VLIW-5 и, таким образом, использовать больше своих потоковых процессоров.

GCN больше похожа на архитектуру Fermi от NVidia, где путь кода к функциональным блокам (ALU и т. Д.) Потоковых процессоров не проходит через явно запланированные инструкции VLIW. Таким образом, большее количество параллелизма может быть автоматически обнаружено во время выполнения, и ваши функциональные блоки будут заняты полезной работой, и вам не придется так много думать о том, как этого добиться.

Вот упрощенный пример, чтобы проиллюстрировать мою точку зрения:

// multiply four factors
// A[0] = B[0] * C[0]
// ...
// A[3] = B[3] * C[3];

float *A, *B, *C;

for (i = 0; i < 4; i ++) {
  A[i] = B[i] * C[i];
}

Этот код, вероятно, будет нормально работать в архитектуре GCN (за исключением неоптимальной производительности доступа к памяти - расширенная тема). Но на вашем HD5870 это было бы катастрофой, потому что эти четыре умножения потребовали бы 4 инструкции VLIW5 вместо 1! Таким образом, вы должны написать этот код, используя тип float4:

float4 A, B, C;

A = B * C;

И это будет очень хорошо работать на обеих ваших картах. Кроме того, он бы надрал задницу в контексте OpenCL процессора и отлично использовал бы широкие регистры MMX / SSE, что является бонусом. Это также гораздо лучшее использование системы памяти.

Вкратце, использование упакованных примитивов - это единственное, о чем я могу порекомендовать помнить, когда вы начинаете развертывание кода в этих двух системах одновременно.

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

// multiply four factors
// as separate work units
// A = B * C

float A, B, C;

A = B * C;

И у нас было четыре отдельных рабочих блока вместо одного. Это было бы абсолютной катастрофой для устройства VLIW и показало бы намного лучшую производительность на устройстве GCN. Это то, на что вы захотите обратить внимание при написании кода - можете ли вы использовать float4 типы, чтобы уменьшить количество рабочих единиц, выполняющих ту же работу? Если да, то вы увидите хорошую производительность на обеих платформах.

person K. Brafford    schedule 19.09.2012
comment
Спасибо за ответ. Я должен был пояснить, что это будет связано с астрофизикой, так что это будет симуляция n тел и столкновения. - person user1604449; 20.09.2012
comment
Значит ли это, что компилятор OpenCL не подходит для векторизации вашего кода за вас, но может легко распаковать векторный код на платформах, где это имеет смысл (например, nVidia)? - person Thomas; 20.09.2012
comment
Компилятор OpenCL не обязательно будет векторизовать ваш код за вас, и да, компилятор всегда может выполнять операции с векторами последовательно, если это необходимо. Я редактирую ответ, чтобы добавить еще один случай, который более четко показывает, что вам нужно сделать, чтобы в полной мере использовать ваше устройство HD5870 (VLIW). - person K. Brafford; 20.09.2012