OpenCL: одно вычислительное устройство на графическом процессоре?

#opencl #gpgpu #gpu

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

Вопрос:

Итак, я запускаю свою программу OpenCL на GeForce GT 610. Я знаю, что CUDA будет лучшей альтернативой, и я могу позже написать версию своего кода на CUDA, однако, чтобы знать, что я пишу на OpenCL, чтобы также иметь возможность работать на видеокартах AMD.

Во время инициализации я выбираю устройство для запуска. Вот что моя программа выводит на этом этапе:

 OpenCL Platform 0: NVIDIA CUDA
 ----- OpenCL Device # 0: GeForce GT 610-----
Gflops: 1.620000
Max Compute Units: 1
Max Clock Frequency: 1620
Total Memory of Device (bytes): 1072889856
Max Size of Memory Object Allocation (bytes): 268222464
Max Work Group Size: 1024
  

Мой вопрос в том, почему он говорит, что максимальная вычислительная единица равна только 1? Согласно спецификации на сайте GeForce, он имеет 48 ядер CUDA. Я знаю, что CUDA работает лучше на картах Nvidia, но действительно ли это так сильно ограничивает его? Nvidia ограничивает OpenCL до 1/48 мощности?

Вот как выглядит мой код, который печатает следующее:

 if (clGetPlatformInfo(platforms[platform], CL_PLATFORM_NAME, sizeof(name), name, NULL)) Fatal("Cannot get OpenCL platform namen");
if (verbose) printf("OpenCL Platform %d: %sn", platform, name);
  

… внутри forloop …

   cl_uint compUnits, freq;
  cl_ulong memSize, maxAlloc;
  size_t maxWorkGrps;

  if (clGetDeviceInfo(id[devId], CL_DEVICE_MAX_COMPUTE_UNITS, sizeof(compUnits), amp;compUnits, NULL)) Fatal("Cannot get OpenCL device unitsn");
  if (clGetDeviceInfo(id[devId], CL_DEVICE_MAX_CLOCK_FREQUENCY, sizeof(freq), amp;freq, NULL)) Fatal("Cannot get OpenCL device frequencyn");
  if (clGetDeviceInfo(id[devId], CL_DEVICE_NAME, sizeof(name), name, NULL)) Fatal("Cannot get OpenCL device namen");

  if (clGetDeviceInfo(id[devId], CL_DEVICE_GLOBAL_MEM_SIZE, sizeof(memSize), amp;memSize, NULL)) Fatal("Cannot get OpenCL memory size.n");
  if (clGetDeviceInfo(id[devId], CL_DEVICE_MAX_MEM_ALLOC_SIZE, sizeof(memSize), amp;maxAlloc, NULL)) Fatal("Cannot get OpenCL memory size.n");

  if (clGetDeviceInfo(id[devId], CL_DEVICE_MAX_WORK_GROUP_SIZE, sizeof(maxWorkGrps), amp;maxWorkGrps, NULL)) Fatal("Cannot get OpenCL max work group sizen");

  int Gflops = compUnits * freq;

  if (verbose) printf(" ----- OpenCL Device # %d: %s-----n"
    "Gflops: %fn"
    "Max Compute Units: %dn"
    "Max Clock Frequency: %dn"
    "Total Memory of Device (bytes): %lun"
    "Max Size of Memory Object Allocation (bytes): %lun"
    "Max Work Group Size: %dn",
    devId,
    name,
    1e-3*Gflops,
    compUnits,
    freq,
    memSize,
    maxAlloc,
    maxWorkGrps);
  

Ответ №1:

Мой вопрос в том, почему он говорит, что максимальная вычислительная единица равна только 1?

Упомянутый здесь вычислительный модуль соответствует NVIDIA GPU SM (потоковый многопроцессорный процессор). Этот графический процессор имеет ровно один SM, внутри которого 48 ядер.

Таким образом, вы не ограничены одним ядром или 1/48-й частью возможностей этого графического процессора. Доступ к этому вычислительному модулю означает, что ваша программа будет иметь доступ к 48 ядрам, содержащимся в нем.

Комментарии:

1. Ах, это имеет смысл. Спасибо. Как бы мне узнать, сколько потоков я могу запускать параллельно на этом устройстве?

2. Вы можете запустить ядро OpenCL, которое использует много потоков (рабочих элементов). Графический процессор будет обрабатывать их с любой скоростью, на которую он способен. Указана мгновенная емкость графического процессора (например, 1536 рабочих элементов могут быть резидентными на единицу Ферми), но это не значит, что вы должны думать о написании программ, которые используют 1536 рабочих элементов для глобального размера (или локального размера, если на то пошло). Используйте настолько большую рабочую структуру, насколько это имеет смысл для вашей проблемы. В этом случае не беспокойтесь о числе 1536.