Подтвердить что ты не робот

Как вычислить Gflops ядра

Я хочу, чтобы оценить максимальную производительность моих архивов ядра.

Скажем, у меня есть NVIDIA Tesla C1060, у которого есть пик GFLOPS 622.08 (~ = 240Cores * 1300MHz * 2). Теперь в моем ядре я подсчитал для каждого потока 16000 флоп (4000 x (2 вычитания, 1 умножение и 1 sqrt)). Поэтому, когда у меня есть 1 000 000 потоков, я бы придумал 16GFLOP. И поскольку ядро ​​занимает 0,1 секунды, я бы архивировал 160GFLOPS, что было бы четвертью максимальной производительности. Теперь мои вопросы:

  • Правильно ли этот подход?
  • Что относительно сравнений (if(a>b) then....)? Должен ли я также учитывать их?
  • Могу ли я использовать профилировщик CUDA для более простых и точных результатов? Я попробовал счетчик instructions, но я не мог понять, что означает цифра.

вопрос с сестрой: Как рассчитать достигнутую пропускную способность ядра CUDA

4b9b3361

Ответ 1

Сначала некоторые общие замечания:

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

Первое, что нужно сделать, - это то, что пиковое значение, которое вы цитируете, предназначено исключительно для инструкций с умножением количества с плавающей запятой (FMAD), которые считаются двумя FLOPS и могут быть удалены с максимальной скоростью один за цикл. Другие операции с плавающей запятой, которые удаляются с максимальной скоростью один за цикл, формально будут классифицироваться только как единый ФЛОП, в то время как другие могут потребовать много циклов, которые должны быть удалены. Поэтому, если вы решили указать производительность ядра на этот пик, вы действительно сравниваете производительность своих кодов с потоком чистых команд FMAD и не более того.

Второй момент заключается в том, что, когда исследователи цитируют значения FLOP/s из фрагмента кода, они обычно используют модельный счетчик FLOP для операции, не пытаясь подсчитывать инструкции. Матричное умножение и тесты Linpack LU-факторизации являются классическими примерами такого подхода к бенчмаркингу производительности. Нижняя граница счета операций этих вычислений точно известна, поэтому рассчитанная пропускная способность - это просто нижняя граница, деленная на время. Фактическое количество команд не имеет значения. Программисты часто используют всевозможные методы, в том числе пробоотборные вычисления, спекулятивные или прогнозирующие вычисления, а также множество других идей для ускорения работы кода. Фактическое количество FLOP такого кода не имеет значения, ссылка всегда является номером модели FLOP.

Наконец, если посмотреть на количественную производительность, обычно есть только две точки сравнения любого реального интереса

  • Выполняется ли версия A кода быстрее, чем версия B, на том же оборудовании?
  • Используется ли аппаратное обеспечение A лучше, чем аппаратное обеспечение B, выполняющее интересующую задачу?

В первом случае вам действительно нужно только измерить время выполнения. Во втором случае подходящей мерой обычно является не FLOP/s, это полезные операции в единицу времени (записи в секунду при сортировке, ячейки в секунду при механическом моделировании жидкости и т.д.). Иногда, как упоминалось выше, полезными операциями может быть модельное число FLOP операции с известной теоретической сложностью. Но фактическая команда с плавающей запятой редко, если вообще когда-либо, входит в анализ.

Если ваш интерес действительно касается оптимизации и понимания производительности вашего кода, то может быть интересен эта презентация Paulius Micikevicius от NVIDIA.

Устранение вопросов о пулевой точке:

Правильно ли этот подход?

Строго говоря, нет. Если вы подсчитываете операции с плавающей запятой, вам нужно знать точное количество FLOP из кода, на котором работает GPU. Операция sqrt может потреблять намного больше, чем один FLOP, в зависимости от его реализации и характеристик числа, на котором он работает, например. Компилятор также может выполнять множество оптимизаций, которые могут изменить фактическое количество операций/команд. Единственный способ получить действительно точный счет - это разобрать скомпилированный код и подсчитать отдельные операнды с плавающей запятой, возможно даже потребовать предположений о характеристиках значений, которые вычислит код.

Как насчет сравнений (если (a > b) тогда....)? Должен ли я также учитывать их?

Они не являются операциями умножения с плавающей запятой, поэтому нет.

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

Не совсем. Профилировщик не может различать конструкцию с плавающей запятой и любой другой тип инструкции, поэтому (по состоянию на 2011 год) подсчет FLOP из фрагмента кода через профилировщик невозможен. [РЕДАКТИРОВАТЬ: см. Greg execellent ответ ниже для обсуждения возможностей подсчета FLOP, доступных в версиях инструментов профилирования, выпущенных с момента написания этого ответа]

Ответ 2

Nsight VSE ( > 3.2) и поддержка Visual Profiler ( >= 5.5). Достигнутый расчет FLOP. Чтобы собрать метрику, профайлеры запускают ядро ​​дважды (используя повтор ядра). В первом повторном воспроизведении количество выполненных команд с плавающей запятой собирается (с пониманием предикации и активной маски). во втором воспроизведении собирается продолжительность.

nvprof и Visual Profiler имеют твердое определение. FMA рассчитывается как 2 операции. Все остальные операции - 1 операция. Счетчики flops_sp_ * - это счет выполнения команд потока, тогда как flops_sp - взвешенная сумма, поэтому некоторый вес может быть применен с использованием отдельных показателей. Однако flops_sp_special охватывает несколько разных инструкций.

Конфигурация эксперимента Nsight VSE позволяет пользователю определять операции по типу инструкции.

Nsight Visual Studio Edition

Настройка сбора достигнутых FLOPS

  • Выполните команду меню Nsight > Начать анализ производительности..., чтобы открыть редактор действий
  • Установите Тип действия на Приложение CUDA профиля
  • В настройках эксперимента установите Эксперименты для запуска на Пользовательские
  • В списке экспериментов добавьте Достигнутые FLOPS
  • В средней панели выберите Достигнутые FLOPS
  • На правой панели вы можете настроить FLOPS на каждую выполненную команду. Значение по умолчанию для FMA и RSQ считается равным 2. В некоторых случаях я видел, что RSQ достигает 5.
  • Запустите сеанс анализа.

Nsight VSE Achieved FLOPS Experiment Configuration

Просмотр достигнутых FLOPS

  • В nvreport откройте страницу отчета CUDA запускает.
  • На странице CUDA Launchches выберите ядро.
  • В области корреляции отчета (внизу слева) выберите Достигнутые FLOPS

Nsight VSE Achieved FLOPS Results

nvprof

Доступные показатели (на K20)

nvprof --query-metrics | grep flop
flops_sp:            Number of single-precision floating-point operations executed by non-predicated threads (add, multiply, multiply-accumulate and special)
flops_sp_add:        Number of single-precision floating-point add operations executed by non-predicated threads
flops_sp_mul:        Number of single-precision floating-point multiply operations executed by non-predicated threads
flops_sp_fma:        Number of single-precision floating-point multiply-accumulate operations executed by non-predicated threads
flops_dp:            Number of double-precision floating-point operations executed non-predicated threads (add, multiply, multiply-accumulate and special)
flops_dp_add:        Number of double-precision floating-point add operations executed by non-predicated threads
flops_dp_mul:        Number of double-precision floating-point multiply operations executed by non-predicated threads
flops_dp_fma:        Number of double-precision floating-point multiply-accumulate operations executed by non-predicated threads
flops_sp_special:    Number of single-precision floating-point special operations executed by non-predicated threads
flop_sp_efficiency:  Ratio of achieved to peak single-precision floating-point operations
flop_dp_efficiency:  Ratio of achieved to peak double-precision floating-point operations

Коллекция и результаты

nvprof --devices 0 --metrics flops_sp --metrics flops_sp_add --metrics flops_sp_mul --metrics flops_sp_fma matrixMul.exe
[Matrix Multiply Using CUDA] - Starting...
==2452== NVPROF is profiling process 2452, command: matrixMul.exe
GPU Device 0: "Tesla K20c" with compute capability 3.5

MatrixA(320,320), MatrixB(640,320)
Computing result using CUDA Kernel...
done
Performance= 6.18 GFlop/s, Time= 21.196 msec, Size= 131072000 Ops, WorkgroupSize= 1024 threads/block
Checking computed result for correctness: OK

Note: For peak performance, please refer to the matrixMulCUBLAS example.
==2452== Profiling application: matrixMul.exe
==2452== Profiling result:
==2452== Metric result:
Invocations                               Metric Name                        Metric Description         Min         Max         Avg
Device "Tesla K20c (0)"
        Kernel: void matrixMulCUDA<int=32>(float*, float*, float*, int, int)
        301                                  flops_sp                             FLOPS(Single)   131072000   131072000   131072000
        301                              flops_sp_add                         FLOPS(Single Add)           0           0           0
        301                              flops_sp_mul                         FLOPS(Single Mul)           0           0           0
        301                              flops_sp_fma                         FLOPS(Single FMA)    65536000    65536000    65536000

ПРИМЕЧАНИЕ: flops_sp = flops_sp_add + flops_sp_mul + flops_sp_special + (2 * flops_sp_fma) (приблизительно)

Визуальный профайлер

Visual Profiler поддерживает показатели, показанные в разделе nvprof выше.