Компания
1 056,21
рейтинг
24 мая 2012 в 11:52

Разработка → Как и зачем мерить FLOPSы

image Как известно, FLOPS – это единица измерения вычислительной мощности компьютеров в (попугаях) операциях с плавающей точкой, которой часто пользуются, чтобы померить у кого больше. Особенно важно померяться FLOPS’ами в мире Top500 суперкомпьютеров, чтобы выяснить, кто же среди них самый-самый. Однако, предмет измерения должен иметь хоть какое-нибудь применение на практике, иначе какой смысл его замерять и сравнивать. Поэтому для выяснения возможностей супер- и просто компьютеров существуют чуть более приближенные к реальным вычислительным задачам бенчмарки, например, SPEC: SPECint и SPECfp. И, тем не менее, FLOPS активно используется в оценках производительности и публикуется в отчетах. Для его измерения давно уже использовали тест Linpack, а сейчас применяют открытый стандартный бенчмарк из LAPACK. Что эти измерения дают разработчикам высокопроизводительных и научных приложений? Можно ли легко оценить производительность реализации своего алгоритма в FLOPSaх? Будут ли измерения и сравнения корректными? Обо всем этом мы поговорим ниже.


Давайте сначала немного разберемся с терминами и определениями. Итак, FLOPS – это количество вычислительных операций или инструкций, выполняемых над операндами с плавающей точкой (FP) в секунду. Здесь используется слово «вычислительных», так как микропроцессор умеет выполнять и другие инструкции с такими операндами, например, загрузку из памяти. Такие операции не несут полезной вычислительной нагрузки и поэтому не учитываются.

Значение FLOPS, опубликованное для конкретной системы, – это характеристика прежде всего самого компьютера, а не программы. Ее можно получить двумя способами – теоретическим и практическим. Теоретически мы знаем сколько микропроцессоров в системе и сколько исполняемых устройств с плавающей точкой в каждом процессоре. Все они могут работать одновременно и начинать работу над следующей инструкцией в конвеере каждый цикл. Поэтому для подсчета теоретического максимума для данной системы нам нужно только перемножить все эти величины с частотой процессора – получим количество FP операций в секунду. Все просто, но такими оценками пользуются, разве что заявляя в прессе о будущих планах по построению суперкомпьютера.

Практическое измерение заключается в запуске бенчмарка Linpack. Бенчмарк осуществляет операцию умножения матрицы на матрицу несколько десятков раз и вычисляет усредненное значение времени выполнения теста. Так как количество FP операций в имплементации алгоритма известно заранее, то разделив одно значение на другое, получим искомое FLOPS. Библиотека Intel MKL (Math Kernel Library) содержит пакет LAPAСK, — пакет библиотек для решения задач линейной алгебры. Бенчмарк построен на основе этого пакета. Cчитается, что его эффективность находится на уровне 90% от теоретически возможной, что позволяет бенчмарку считаться «эталонным измерением». Отдельно Intel Optimized LINPACK Benchmark для Windows, Linux и MacOS можно качать здесь, либо взять в директории composerxe/mkl/benchmarks, если у вас установлена Intel Parallel Studio XE.

Очевидно, что разработчики высокопроизводительных приложений хотели бы оценить эффективность имплементации своих алгоритмов, используя показатель FLOPS, но уже померянный для своего приложения. Сравнение измеренного FLOPS с «эталонным» дает представление о том, насколько далека производительность их алгоритма от идеальной и каков теоретический потенциал ее улучшения. Для этого всего-навсего нужно знать минимальное количество FP операций, требуемое для выполнения алгоритма, и точно измерить время выполнения программы (ну или ее части, выполняющей оцениваемый алгоритм). Такие результаты, наряду с измерениями характеристик шины памяти, нужны для того, чтобы понять, где реализация алгоритма упирается в возможности аппаратной системы и что является лимитирующим фактором: пропускная способность памяти, задержки передачи данных, производительность алгоритма, либо системы.

image

Ну а теперь давайте покопаемся в деталях, в которых, как известно, все зло. У нас есть три оценки/измерения FLOPS: теоретическая, бенчмарк и программа. Рассмотрим особенности вычисления FLOPS для каждого случая.

Теоретическая оценка FLOPS для системы
Чтобы понять, как подсчитывается количество одновременных операций в процессоре, давайте взглянем на устройство блока out-of-order в конвеере процессора Intel Sandy Bridge.

image

Здесь у нас 6 портов к вычислительным устройствам, при этом, за один цикл (или такт процессора) диспетчером может быть назначено на выполнение до 6 микроопераций: 3 операции с памятью и 3 вычислительные. Одновременно могут выполняться одна операция умножения (MUL) и одна сложения (ADD), как в блоках x87 FP, так и в SSE, либо AVX. С учетом ширины SIMD регистров 256 бит мы может получить следующие результаты:

image

8 MUL (32-bit) и 8 ADD (32-bit): 16 SP FLOP/cycle, то есть 16 операций с плавающей точкой одинарной точности за один такт.
4 MUL (64-bit) и 4 ADD (64-bit): 8 DP FLOP/cycle, то есть 8 операций с плавающей точкой двойной точности за один такт.

Теоретическое пиковое значение FLOPS для доступного мне 1-сокетного Xeon E3-1275 (4 cores @ 3.574GHz) составляет:
16 (FLOP/cycle)*4*3.574 (Gcycles/sec)= 228 GFLOPS SP
8 (FLOP/cycle)*4*3.574 (Gcycles/sec)= 114 GFLOPS DP

Запуск бенчмарка Linpack
Запускам бенчмарк из пакета Intel MKL на системе и получаем следующие результаты (порезано для удобства просмотра):

image

Здесь нужно сказать, как именно учитываются FP операции в бенчмарке. Как уже упоминалось, тест заранее «знает» количество операций MUL и ADD, которые необходимы для перемножения матриц. В упрощенном представлении: производится решение системы линейных уравнений Ax=b (несколько тысяч штук) путем перемножения плотных матриц действительных чисел (real8) размером MxK, а количество операций сложения и умножения, необходимых для реализации алгоритма, считается (для симметричной матрицы) Nflop = 2*(M^3)+(M^2). Вычисления производятся для чисел с двойной точностью, как и для большинства бенчмарков. Сколько операций с плавающей точкой действительно выполняется в реализации алгоритма, пользователей не волнует, хотя они догадываются, что больше. Это связано с тем, что выполняется декомпозиция матриц по блокам и преобразование (факторизация) для достижения максимальной производительности алгоритма на вычислительной платформе. То есть нам нужно запомнить, что на самом деле значение физических FLOPS занижено за счет неучитывания лишних операций преобразования и вспомогательных операций типа сдвигов.

Оценка FLOPS программы
Чтобы исследовать соизмеримые результаты, в качестве нашего высокопроизводительного приложения будем использовать пример перемножения матриц, сделанный «своими руками», то есть без помощи математических гуру из команды разработчиков MKL Performance Library. Пример реализации перемножения матриц, написанный на языке С, можно найти в директории Samples пакета Intel VTune Amplifier XE. Воспользуемся формулой Nflop=2*(M^3) для подсчета FP операций (исходя из базового алгоритма перемножения матриц) и померим время выполнения перемножения для случая алгоритма multiply3 при размере симметричных матриц M=4096. Для того, чтобы получить эффективный код, используем опции оптимизации –O3 (агрессивная оптимизация циклов) и –xavx (использовать инструкции AVX) С-компилятора Intel для того, чтобы сгенерировались векторные SIMD-инструкции для исполнительных устройств AVX. Компилятор нам поможет узнать, векторизовался ли цикл перемножения матрицы. Для этого укажем опцию –vec-report3. В результатах компиляции видим сообщения оптимизатора: «LOOP WAS VECTORIZED» напротив строки с телом внутреннего цикла в файле multiply.c.

image

На всякий случай проверим, какие инструкции сгенерированы компилятором для цикла перемножения.
$icl –g –O3 –xavx –S
По тэгу __tag_value_multiply3 ищем нужный цикл — инструкции правильные.

$vi muliply3.s
image

Результат выполнения программы (~7 секунд)
image

нам дает следующее значение FLOPS = 2*4096*4096*4096/7[s] = 19.6 GFLOPS
Результат, конечно, очень далек от того, что получается в Linpack, что объясняется исключительно квалификционной пропастью между автором статьи и разработчиками библиотеки MKL.

Ну, а теперь дессерт! Собственно то, ради чего я затеял свое исследование этой, вроде бы скучной и давно избитой, темы. Новый метод измерения FLOPS.

Измерение FLOPS программы
Существуют задачи в линейной алгебре, программную имплементацию решения которых очень сложно оценить в количестве FP операций, в том смысле, что нахождение такой оценки само является нетривиальной математической задачей. И тут мы, что называется, приехали. Как считать FLOPS для программы? Есть два пути, оба экспериментальных: трудный, дающий точный результат, и легкий, но обеспечивающий приблизительную оценку. В первом случае нам придется взять некую базовую программную имплементацию решения задачи, скомпилировать ее в ассемблерные инструкции и, выполнив их на симуляторе процессора, посчитать количество FP операций. Звучит так, что резко хочется пойти легким, но недостоверным путем. Тем более, что если ветвление исполнения задачи будет зависеть от входных данных, то вся точность оценки сразу поставится под сомнение.

Идея легкого пути состоит в следующем. Почему бы не спросить сам процессор, сколько он выполнил FP инструкций. Процессорный конвеер, конечно же, об этом не ведает. Зато у нас есть счетчики производительности (PMU – вот тут про них интересно), которые умеют считать, сколько микроопераций было выполнено на том или ином вычислительном блоке. С такими счетчиками умеет работать VTune Amplifier XE.

Несмотря на то, что VTune имеет множество встроенных профилей, специального профиля для измерения FLOPS у него пока нет. Но никто не мешает нам создать наш собственный пользовательский профиль за 30 секунд. Не утруждая вас основами работы с интерфейсом VTune (их можно изучить в прилагающимся к нему Getting Started Tutorial), сразу опишу процесс создания профиля и сбора данных.

  1. Создаем новый проект и указываем в качестве target application наше приложение matrix.
  2. Выбираем профиль Lightweight Hotspots (который использует технологию сэмплирования счетчиков процессора Hadware Event-based Sampling) и копируем его для создания пользовательского профиля. Обзываем его My FLOPS Analysis.
  3. Редактируем профиль, добавляем туда новые процессорные счетчики событий процессора Sandy Bridge (Events). На них остановимся чуть подробнее. В их названии зашифрованы исполнительные устройства (x87, SSE, AVX) и тип данных, над которыми выполнялась операция. Каждый такт процессора счетчики складывают количество вычислительных операций, назначенных на исполнение. На всякий случай мы добавили счетчики на все возможные операции с FP:

  • FP_COMP_OPS_EXE. SSE_PACKED_DOUBLE – векторы (PACKED) данных двойной точности (DOUBLE)
  • FP_COMP_OPS_EXE. SSE_PACKED_SINGLE – векторы данных одинарной точности
  • FP_COMP_OPS_EXE. SSE_SCALAR_DOUBLE – скалярые DP
  • FP_COMP_OPS_EXE. SSE_ SCALAR _SINGLE – скалярные SP
  • SIMD_FP_256.PACKED_DOUBLE – векторы AVX данных DP
  • SIMD_FP_256.PACKED_SINGLE – векторы AVX данных SP
  • FP_COMP_OPS_EXE.x87 – скалярые данные x87

Нам остается только запустить анализ и подождать результатов. В полученных результатах переключаемся в Hardware Events viewpoint и копируем количетво events, собранных для функции multiply3: 34,648,000,000.

image

Далее мы просто подсчитываем значения FLOPS по формулам. Данные у нас были собраны для всех процессоров, поэтому умножение на их количество здесь не требуется. Операции данными двойной точности выполняются одновременно над четырмя 64-битными DP операндами в 256-битном регистре, поэтому умножаем на коэффициент 4. Данные с одинарной точностью, соответственно, умножаем на 8. В последней формуле не умножаем количество инструкций на коэффициент, так как операции сопроцессора x87 выполняются только со скалярными величинами. Если в программе выполняется несколько разных типов FP операций, то их количество, умноженное на коэффициенты, суммируется для получения результирующего FLOPS.

FLOPS = 4 * SIMD_FP_256.PACKED_DOUBLE / Elapsed Time
FLOPS = 8 * SIMD_FP_256.PACKED_SINGLE / Elapsed Time
FLOPS = (FP_COMP_OPS_EXE.x87) / Elapsed Time

В нашей программе выполнялись только AVX инструкции, поэтому в результатах есть значение только одного счетчика SIMD_FP_256.PACKED_DOUBLE.
Удостоверимся, что данные события собраны для нашего цикла в функции multiply3 (переключившись в Source View):

image

FLOPS = 4 *34.6Gops/7s = 19.7 GFlops
Значение вполне соответствует оценочному, подсчитанному в предыдущем пункте. Поэтому с достаточной долей точности можно говорить о том, что результаты оценочного метода и измерительного совпадают. Однако, существуют случаи, когда они могут не совпадать. При определенном интересе читателей, я могу заняться их исследованием и рассказать, как использовать более сложные и точные методы. А взамен очень хочется услышать о ваших случаях, когда вам требуется измерение FLOPS в программах.

Заключение
FLOPS – единица измерения производительности вычислительных систем, которая характеризует максимальную вычислительную мощность самой системы для операций с плавающей точкой. FLOPS может быть заявлена как теоретическая, для еще не существующих систем, так и измерена с помощью бенчмарков. Разработчики высокопроизводительных программ, в частности, решателей систем линейных дифференциальных уравнений, оценивают производительность реализации своих алгоритмов в том числе и по значению FLOPS программы, вычисленному с помощью теоретически/эмпирически известного количества FP операций, необходимых для выполнения алгоритма, и измеренному времени выполнения теста. Для случаев, когда сложность алгоритма не позволяет оценить количество FP операций алгоритма, их можно измерить с помощью счетчиков производительности, встроенных в микропроцессоры Intel.
Автор: @vtsymbal
Intel
рейтинг 1 056,21

Комментарии (32)

  • +1
    > А в замен очень хочется услышать о ваших случаях, когда вам требуется измерение FLOPS в программах

    Вычислял округленно «на бумажке» FLOPS'ы при выборе процессора для разработки.
    Собственно там был даже комплекс измерений, так как нужно была не только знать производительность процессора, но и ширину шины, и размер кэша.
    PS: «взамен», конечно же, слитно :)
    • 0
      Спасибо, поправил.
      «На бумажке» вычислялось требования по FLOPS'ам алгоритма?
      Как ширина шины влияет на измерения?
      • 0
        > «На бумажке» вычислялось требования по FLOPS'ам алгоритма?
        Угу, требуемое количество double-fp операций в секунду.
        > Как ширина шины влияет на измерения?
        На flops'ы — никак. Но flops был не единственный определяющий фактор. Код довольно активно работал с памятью, поэтому битность шины тоже выбиралась соответствующая задаче. Собственно в упрощении до минимума задача звучала так: «мы хотим обрабатывать XXX байт данных алгоритмом Y не больше чем за T». С маленькой шиной пропускная способность контроллера памяти являлась лимитирующей, просто потому что за N тактов процессор не получал весь объем данных.
        Несовпадение тактов с памятью оказывала куда меньшее влияние. По крайне мере, мне так казалось, да и по расчетам тоже выходили потери буквально 10-15% если пропускаем половину процессорного такта, но с широкой шиной.
        • 0
          Меня просто смутило то, что физическая ширина шины учитывалась как параметр. Обычно в рассчетах используют максимальную пропускную способность. Например, если я правильно помню, P4 умел зашвыривать в кэш сразу две линейки из памяти, по фронту и спаду одного такта (как раз чтобы смягчить проблему скорости загрузки данных в FP-модуль из-зи ширины шины).
  • +4
    Жаль не могу голосовать. Поставил бы + Очень полезная и нужная статья
  • 0
    Эхх, где же купить оптические процессоры:
    p.s. например этот, созданный 2003-году и скорее всего загнобленный мэтрами покрупнее. Под него lapack идеально оптимизирован (собственно процессор умеет только матрицы перемножать, но со скоростью 8 TeraMAC, MAC — multiply accumulae operations per second), а в от другие алгоритмы уже не так красиво ложатся.
    • 0
      Есть инструкции FMA, под них тоже бенчмарки идеально оптимизированы. Этот набор инструкций уже поддерживается в АМД Бульдозер и будут поддерживаться в следующем процессоре Intel Haswell.
      • 0
        А в ARM уже давно инструкция MLA есть :)
        Правда насчет SIMD'a сомневаюсь.
        • 0
          SIMD в ARM'e тоже есть, но толко для 8/16-битных данных. Неон расширил до 128-бит. Но MLA-инструкция, как я понимаю, с SIMD регистрами работать не может, как и с FP-данными. Может я и ошибаюсь.
          • 0
            Я как раз и выразил сомнения в том, что есть SIMD-аналог MLA.
            Для FP точно есть — VMLA. Причем с самых первых VFP.
            Проверил только что, есть и для NEON'a.
            • 0
              К сожалению, мои познания в ARM-архитектуре перестали обновляться где-то во времена TI OMAP первого поколения…
  • 0
    Статья замечательная, но главный вопрос — где купить такие тапки?
    • 0
      Если поясните, какие тапки имеются ввиду, то может я могу подсказать?
      • 0
        Вот эти :)
        image
        • +2
          Из названия поста очевидно же, что это не тапки, а шлепки (flip-flops) :)
          Ну да ладно, вот они, а цена меньше 20-ти баксов без пересылки (эти ребята теперь мне должны роялити за рекламу :)
  • 0
    FLOPS'ы — очень экзотическая величина. Интересна только если числомолотилка занята вычислениями.

    А у меня в хозяйстве более всего загружены процессоры, занятые перекладыванием байтиков из одного места в другое с минимальной обработкой.

    А float point я вижу только в попугаемерках, которые int на dt делят.
  • 0
    Измерил на ноуте — вышло 8 гигафлопс, эх

    i5, CPU frequency: 2.521 GHz
    Number of CPUs: 1
    Number of cores: 2
    Number of threads: 4
    • 0
      Такой обреченный «эх» в конце предложения :) Это вполне даже много. Суперкомп Cray Y-MP (построен в 1988 году) имел суммарно 2,3 Гфлопс.
      Напишите программу, которая попробует эти 8 Гфлопс использовать.
      • 0
        когда то и 400кб памяти хватало всем )

        в том то и дело, что на практике производительность существенно ниже: и система забирает часть ресурсов, да и ввод/вывод тоже, так что монтекарлить с такими ресурсами не очень удобно )
        • 0
          Я не знаю, как система может забирать часть ресурсов (если только не работают активно какое-нибудь индексирование и антивирусы).
          Попробовал «помонтекарлить» на своей машине — вычисление числа пи методом Монтекарло. Сходу получиось только .2 GFLOPS померенных программой. При определенном усилии удалось поднять до 1.2. Вижу пути поднять еще больше, но требуется использование VML библиотеки. И все-равно все возможности машины не использованы.
          • 0
            ну а что, например у меня работает в фоне? дропбокс, системный монитор, компиз и прочее, почему то, жрут процессор, как заведенные. И если во время теста этого всего не было, то при нормальной работе от этого уйти сложно.

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

    • 0
      Мой рабочий 4-5ти летний PentiumD показал ~7,6.
      А виртуалка с выделенным 1м ядром Xeon E5310 (1,6 ГГц) с W7x86 на борту — 4,3.
      • 0
        не слабо, разгоняли?)
        • 0
          Сам в шоке. В том-то и дело что не разогнан.
          image
          • 0
            скорее всего потому, что частота больше, да и размеры кэша неизвестно как соотносится, ведь бенчмарк там неслабыми матрицами ворочает.
            • 0
              Xeon E5310 при вдвое меньшей частоте дает такие показатели, и это в виртуальной машине.
              Тут частота конечно влияет и кэш. Но i5 должен и кэша поболе иметь и операции «умнее» выполнять по идее.
              • 0
                Да, странно и несколько печально.
                Надо будет прогнать тест еще пару раз, но вряд ли, конечно, что то кардинально измениться.
                Интересно, атом сколько покажет, надеюсь, что хотя бы полгига.
                • 0
                  Надо бы запустить на какой-нить серьезной машине. Сейчас жалко нет серверов свободных, а то бы скормить эту программулину базаданческому серверу или Exchange-у у которых по 16 Xeon-ных ядер. Аж интересно, какова будет разница.
                  • 0
                    жаль, что нет проекта для шаринга подобной информации
  • 0
    Зашла специально сказать, что это — великий пост. Я уже ровно 4 года посылаю к нему всех, интересующихся FLOPS, и они больше даже ничего не спрашивают — все понятно отныне и вовеки веков. Спасибо еще раз!
    • 0
      Спасибо за эту приувеличенную оценку важности моего поста :)
      А вообще надо бы обновить статью — воды и силикона с тех пор много утекло…
      • 0
        пожалуйста :) Но я думаю, поменялись только абсолютные цифры, все остальное — вечно, так что можешь сэкономить силы.

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.

Самое читаемое Разработка