1

Я пытаюсь понять архитектуру графического процессора Nvidia, но я немного застрял на чем-то, что кажется довольно простым. Каждый потоковый мультипроцессор в Pascal состоит из ядер 64xFP32 и 32xFP64. И вот мои два вопроса:

  • Почему Nvidia поместила в чип модули FP32 и FP64? Почему бы просто не поставить модули FP64, способные выполнять 2xFP32 операции на одну инструкцию (например, наборы команд SIMD в ЦП).
  • Почему я не могу использовать все устройства FP32 и FP64 одновременно?

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

EDIT1:

  • Если возможно выполнять FP32 и FP64 одновременно, означает ли это, что графический процессор с 8TFLOPS SP и 4TFLOPS DP может дать (теоретически) 12 TFLOPS смешанных TFLOPS?
    • В случае CUDA, как это достигается? Я просто использую double и float одновременно в моем ядре? Или мне нужно передать какой-то флаг в NVCC?

1 ответ1

2

Почему Nvidia поместила в чип модули FP32 и FP64?

Я думаю о проникновении на рынок, чтобы продать как можно больше. Без FP64 ребята, занимающиеся научными исследованиями, не могут даже попробовать демонстрацию научно значимого программного обеспечения gpgpu, которое использует FP64(и даже игры могут использовать некоторую двойную точность в некоторых случаях). Без FP32 физика игры и симуляции были бы очень медленными, или GPU потребовал бы ядерного реактора. Без FP16 нет быстрой нейронной сети. Если бы был только FP32, симуляция нейронной сети работала бы с половинной скоростью, или некоторое суммирование FP64 не сработало бы.

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

В конечном счете, я бы не сказал "нет" для GPU на основе FPGA, который может преобразовывать некоторые ядра из FP64 в FP32 или некоторые специальные функциональные ядра для приложения, затем преобразовывать все в FP64 для другого приложения и даже преобразовывать все в одно толстое ядро, которое выполняет последовательную работу (например, компиляция шейдеров). Это было бы полезно для людей, делающих много разных вещей на компьютере. Например, мне может понадобиться больше умножений, чем дополнений, и FPGA может помочь здесь. Но теперь деньги говорят и говорят "фиксированная функция на данный момент", и лучший доход достигается при сочетании FP64 и FP32 (и FP16 в последнее время).

Почему бы просто не поставить модули FP64, способные выполнять 2xFP32 операции на одну инструкцию (например, наборы команд SIMD в ЦП).

SIMD ожидает всегда одну и ту же операцию для нескольких данных и меньше удовольствия для скалярных ядер GPGPU. ТАКЖЕ для изготовления 2xFP32 из FP64 потребуется больше транзисторов, чем у чистого FP64, больше тепла, может быть больше задержки.

Чем больше транзисторов, тем больше вероятность сбоя в работе, поэтому более вероятно, что 1024 FP32 GPU будет произведено, чем 512 FP64_furable GPU.

Почему я не могу использовать все устройства FP32 и FP64 одновременно?

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

Ответ на редактирование 1:

вот подробный источник http://www.nvidia.com/content/PDF/sc_2010/CUDA_Tutorial/SC10_Accelerating_GPU_Computation_Through_Mixed-Precision_Methods.pdf

Короче говоря, они не добавляют, что есть "убывающая отдача", которая почему-то не позволяет масштабировать% 100 на всех ядрах из-за необходимых "дополнительных циклов" между вычислениями с различной точностью. Когда они не смешаны, им нужны "дополнительные итерации" между блоками, которые также не позволяют масштабировать% 100. Кажется, это более полезно, так как ускорение "FP64" вместо "FP32" вниз (но наличие многих ядер FP64 должно быть выгодно (для повышения FP32), вы можете протестировать их с чем-то вроде ядра nbody (которое не является узким местом в памяти)). FP64 потребляет очень много памяти (и строк кэша (и локальной памяти)), поэтому я предложил nbody алгоритм, который повторно использует некоторые данные для N (> 64k, например) раз. Мой GPU имеет мощность 1/24 FP64, поэтому я не доверяю своему компьютеру. У тебя есть титан? Вы должны попробовать, может быть, он имеет на 50% больше энергии, чем его рекламные значения GFLOP (но рекламное значение TDP может ограничить его частоту и таять)

Этот источник: http://www.nvidia.com/content/nvision2008/tech_presentations/NVIDIA_Research_Summit/NVISION08-Mixed_Precision_Methods_on_GPUs.pdf

говорит "выдающаяся производительность и точность", но я не мог найти физический решатель для игр, использующих FP32 + FP32(усеченный FP64), возможно, его деньги говорят снова, если кто-то сделает это, это будет "выдающаяся производительность и крушение" в играх.(может быть, хуже, чем Furmark взрывающаяся Gpus)

люди даже используют целые числа (произведение целочисленных точек) поверх чисел здесь: https://devblogs.nvidia.com/parallelforall/mixed-precision-programming-cuda-8/

В случае CUDA, как это достигается? Я просто использую double и float одновременно в моем ядре? Или мне нужно передать какой-то флаг в NVCC?

Пример итеративного уточнения с использованием fp64+fp32 в той же функции:

https://www.sciencesmaths-paris.fr/upload/Contenu/HM2012/07-dongarra_part2.pdf

страницы 26-28.


Для части opencl, это amd evergreen(серия hd5000), способный выдавать 1dp fma + 1 sp(или 1 sf) каждый цикл.

http://www.microway.com/download/whitepaper/gpgpu_architecture_and_performance_comparison_2010.pdf

Я протестирую что-то вроде nbody на моем R7-240, который будет 1/24 или 1/26-й степени fp32 как fp64 завтра.

Редактировать: это работает.

__kernel void sumGPU(__global float * a,__global float * b)
{
  int idx = get_global_id(0);
  float a0=a[idx];
  a0+=2.0f;
  a0+=2.0f;
  a0+=2.0f;
  a0+=2.0f;
  a0+=2.0f;
  a0+=2.0f;
  a0+=2.0f;
  a0+=2.0f;
  a0+=2.0f;
  a0+=2.0f;
  a0+=2.0f;
  a0+=2.0f;
  //a0=convert_float(convert_double(a0)+2.0);
  //a0+=2.0f;
  a0+=2.0f;
  a0+=2.0f;
  a0+=2.0f;
  a0+=2.0f;
  a0+=2.0f;
  a0+=2.0f;
  a0+=2.0f;
  a0+=2.0f;
  a0+=2.0f;
  a0+=2.0f;
  a0+=2.0f;
  a0+=2.0f;
  a0+=2.0f;
  a0+=2.0f;
  a0+=2.0f;
  a0+=2.0f;
  a0+=2.0f;
  a0+=2.0f;
  a0+=2.0f;
  a0+=2.0f;
  a0+=2.0f;
  b[idx] = a0;

}   

он переключается между 13,02 и 12,85 мс, когда отключен только один из комментариев.


Примечание: ядра не являются самими fp32. Нету ядер. Существуют планировщики, связывающие аппаратные ресурсы (fp32, fp64, special_function, registers) с инструкциями ядра потоков. Темы тоже не настоящие темы. Поэтому, когда вы используете fp32, затем fp64, затем fp32, затем fp64_square_root, он зарезервирует необходимые ресурсы, когда они понадобятся. Когда нет, они являются опциями для других рабочих элементов (но один рабочий элемент не может использовать более 1-2 fp32 ALU, которые я подозреваю (IDK, я сделал это))


Редактировать (2018/03): FP_raytrace (второй абзац этого ответа выше) становится реальностью?

(NVIDIA)https://www.geforce.com/whats-new/articles/nvidia-rtx-real-time-game-ray-tracing

(AMD)https://www.gamingonlinux.com/articles/amd-has-announce-radeon-rays-an-open-source-ray-tracing-sdk-using-vulkan.11461

Или это еще один маркетинговый трюк? Если у него есть аппаратная сторона, то люди, работающие с Raytracer, могут работать быстрее, но это не поможет для мобайтера или симулятора физики без лучей. Зачем мне платить больше за эти трассировщики лучей, если я собираюсь редактировать некоторые видео? Может быть, они тоже могут быть сегментированы как другие, но, возможно, за большие деньги.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .