popcnt в OpenCL?

#cuda #opencl #gpu

#cuda #opencl #графический процессор

Вопрос:

Новые графические процессоры NVIDIA поддерживают инструкцию __popc(x), которая подсчитывает количество битов, установленных в 32-разрядном регистре.

Я уверен, что на 99% OpenCL не поддерживает встроенный ассемблер, если только это не расширение ядра поставщика.

1) Поддерживает ли аппаратное обеспечение AMD это уже? (Я не в курсе этого).

2) Для OS X и Linux, как вы перехватываете промежуточный язык NVIDIA, на который он скомпилирован, чтобы вы могли вставить это?

Я выяснил, как выгрузить «двоичный файл» PTX в PyOpenCL, теперь мне просто нужно выяснить, как повторно вставить его с изменениями.

 #create the program
self.program = cl.Program(self.ctx, fstr).build()
print self.program.BINARIES[0]
  

Ответ №1:

NVCC от NVIDIA поддерживает встроенную сборку PTX внутри кода OpenCL с использованием ключевого слова ‘asm’. Нотация похожа на встроенную сборку GCC. В настоящее время я использую это:

 inline uint popcnt(const uint i) {
  uint n;
  asm("popc.b32 %0, %1;" : "=r"(n) : "r" (i));
  return n;
}
  

Протестировано и работает на Ubuntu Linux.

Если вам нужна дополнительная информация, ознакомьтесь с примером кода oclInlinePTX от NVIDIA и документацией PTX ISA.

Если вы используете карту AMD или Intel, это не имеет значения, поскольку вы можете просто использовать встроенную инструкцию popcount в OpenCL 1.2.

Ответ №2:

Насколько мне известно, ни в одной текущей реализации OpenCL нет встроенной сборки, и нет никакого способа перехватить PTX (или CAL) во время цикла компиляции JIT в OS X или Linux.

popc это аппаратная инструкция на оборудовании NVIDIA compute 2.x, но на оборудовании compute 1.x она эмулируется. Вы можете найти код для этого в device_functions.h в CUDA toolkit. Вы всегда могли бы реализовать это как функцию в OpenCL, за счет некоторой скорости.