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

Что такое FLOP/s и является ли это хорошей мерой производительности?

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

Я провел некоторое исследование того, что такое FLOP, и у меня есть довольно противоречивые ответы. Одним из самых популярных ответов я получил: 1 FLOP = дополнение и операция умножения. Это правда? Если это так, опять же, физически, что именно это означает?

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

Какими будут другие, эффективные способы измерения производительности в моем случае (резюме моего дела "fortran code", который много раз выполняет арифметические вычисления в течение нескольких дней на нескольких сот ЦП)?

4b9b3361

Ответ 1

Это довольно приличный показатель производительности, если вы точно понимаете, что он измеряет.

FLOPS, так как название подразумевает OPOATIONS FLOating point в секунду, именно то, что составляет FLOP, может варьироваться в зависимости от процессора. (Некоторые процессоры могут выполнять сложение и умножение как одну операцию, другие, например, не могут). Это означает, что в качестве показателя производительности он довольно близок к оборудованию, а это означает, что 1) вы должны знать свое оборудование, чтобы вычислить идеальные FLOPS на данной архитектуре, и вы должны знать свой алгоритм и реализацию, чтобы выяснить, как многие операторы с плавающей запятой фактически состоят из.

В любом случае, это полезный инструмент для изучения того, насколько хорошо вы используете CPU. Если вы знаете теоретическую пиковую производительность процессора в FLOPS, вы можете решить, насколько эффективно вы используете процессоры с плавающей запятой, которые часто являются одними из трудных для эффективного использования. Программа, которая запускает 30% FLOPS, на которые способен процессор, имеет место для оптимизации. Вероятно, что скорость, достигающая 70%, не будет более эффективной, если вы не измените базовый алгоритм. Для математических алгоритмов, подобных вашим, это в значительной степени стандартный способ измерения производительности. Вы можете просто измерить, сколько времени требуется программе для запуска, но это зависит от процессора. Но если ваша программа имеет 50% загрузки процессора (относительно максимального значения FLOPS), это несколько более постоянное значение (оно по-прежнему будет варьироваться между радикально разными архитектурами ЦП, но оно намного более последовательное, чем время выполнения).

Но зная, что "мой процессор способен X GFLOPS, и я на самом деле достигал пропускной способности, скажем, 20% от этого", является очень ценной информацией в высокопроизводительном программном обеспечении. Это означает, что что-то другое, чем операторы с плавающей запятой, удерживает вас и не позволяет функциям FP эффективно работать. И поскольку единицы FP составляют основную часть работы, это означает, что у вашего программного обеспечения есть проблемы.

Легко измерить "Моя программа работает через X минут", и если вы чувствуете, что это неприемлемо, тогда вы можете пойти "Интересно, могу ли я отрубить 30% от этого", но вы не знаете, возможно, если вы точно не определяете, сколько работы выполняется, и точно, на что способен процессор на пике. Сколько времени вы хотите потратить на оптимизацию, если вы даже не знаете, может ли процессор в принципе работать с любыми инструкциями в секунду?

Очень легко предотвратить эффективное использование блока CPU FP из-за слишком большого количества зависимостей между операциями FP или наличием слишком большого количества ветвей или аналогичного предотвращения эффективного планирования. И если это то, что удерживает вашу реализацию назад, вам нужно это знать. Вы должны знать, что "я не получаю пропускную способность FP, которая должна быть возможной, поэтому четкие другие части моего кода предотвращают доступ к инструкциям FP, когда процессор готов к выпуску".

Зачем вам нужны другие способы измерения производительности? Что плохого в том, чтобы просто разработать FLOPS, как вас спросил ваш босс?;)

Ответ 2

Я просто хотел бы добавить пару более тонких точек:

  • деление является особенным. Поскольку большинство процессоров могут выполнять добавление, сравнение или умножение за один цикл, все они считаются одним флопом. Но деление всегда занимает больше времени. Насколько дольше зависит процессор, но в сообществе HPC есть стандарт defacto, чтобы подсчитать одно деление на 4 флопа.

  • Если в процессоре есть команда с плавным умножением-добавления, которая выполняет умножение и добавление в одной команде - обычно A + = B * C -, которая считается как 2 операции.

  • Всегда будьте осторожны при различении одиночной точности флопов и прокрутки двойной точности. Процессор, способный к столь большому количеству гигафлоп с одной точностью, может быть способен только на небольшую часть этого количества гигафлоп с двойной точностью. Процессоры AMD Athlon и Phenom обычно могут выполнять вдвое меньше, чем одноточечные. Процессоры ATI Firestream, как правило, делают 1/5-ю тактовку с двойной точностью как одиночную точность. Если кто-то пытается продать вам процессор или пакет программного обеспечения, и они просто цитируют провалы, не сказав, что вы должны называть их.

  • Используются термины megaflop, gigaflop, teraflop и т.д. Они относятся к факторам 1000, а не к 1024. Например, 1 мегафлоп = 1 000 000 флопов/сек не 1,048,576. Как и в случае с размерами дисковых накопителей, есть некоторые путаницы в этом.

Ответ 3

"сравнить результаты с эталонами" и сделать что?

FLOPS означает, что вам нужно

1) FLOP на одну единицу работы.

2) время для этой единицы работы.

Скажем, у вас есть файл ввода, который выполняет 1000 итераций через некоторый цикл. Цикл - удобная единица работы. Выполняется 1000 раз. Это занимает час.

В цикле есть несколько добавлений и умножений, а также несколько делений и квадратный корень. Вы можете считать, добавляет, умножает и делит. Вы можете считать это в источнике, ища +, * и /. Вы можете найти выход на языке ассемблера из компилятора и посчитать их там. Вы можете получить разные цифры. Какой из них прав? Спросите своего начальника.

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

Теперь вы знаете FLOPS в своем цикле. И вы знаете время, чтобы запустить его 1000 раз. Вы знаете FLOPS в секунду.

Затем вы смотрите на LINPACK и находите, что вы медленнее. Что теперь? Ваша программа не LINPACK, а медленнее LINPACK. Коэффициенты действительно хороши, что ваш код будет медленнее. Если ваш код не был написан и не оптимизирован за такое же количество лет, LINPACK, вы будете медленнее.

Здесь другая часть. У вашего процессора есть определенный рейтинг FLOPS против различных тестов. Ваш алгоритм не является одним из тех тестов, поэтому вам не хватает контрольных показателей. Это плохо? Или это очевидное следствие того, что вы не являетесь эталоном?

Каким будет результат действия?

Измерение по сравнению с некоторой базой кода теста только скажет вам, что вы алгоритм не является эталонным алгоритмом. Это предрешено, что вы будете другими; обычно медленнее.

Очевидно, что результат измерения против LINPACK будет: (a) вы отличаетесь и, следовательно, (b) вам нужно оптимизировать.

Измерение действительно действительно полезно, когда вы делаете это самостоятельно. Не какое-то гипотетическое сочетание команд, а ваше собственное сочетание команд. Измерьте свою собственную производительность. Изменить. Посмотрите, улучшается ли ваша производительность - по сравнению с вами - лучше или хуже.

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

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

Ответ 4

Старый вопрос со старыми, если популярными, ответами, которые не совсем велики, ИМО.

"FLOP" - математическая операция с плавающей запятой. "FLOPS" может означать одну из двух вещей:

  • Простое множественное число "FLOP" (то есть "операция X принимает 50 FLOP" )
  • Скорость FLOPs в первом смысле (т.е. математические операции с плавающей запятой в секунду)

В тех случаях, когда из контекста неясно, какое из них подразумевается, часто устраняется неоднозначно, написав первое как "FLOPs", а второе - как "FLOP/s".

FLOPs так называются, чтобы отличать их от других видов операций ЦП, таких как операции с целыми числами, логические операции, побитовые операции, операции с памятью и ветвящиеся операции, которые имеют разные затраты (читайте "принимать разные промежутки времени" ), связанных с ними.

Практика "подсчета ФЛП" относится к самым ранним периодам научных вычислений, когда ФЛП были, относительно говоря, чрезвычайно дорогими, занимая много циклов ЦП каждый. Например, математический сопроцессор 80387 занимал примерно 300 циклов для одного умножения. Это было в то время, прежде чем конвейерная обработка и до того, как разброс между тактовыми частотами процессора и скоростями памяти действительно открылся: операции памяти заняли всего один цикл или два, а разветвление ( "принятие решений" ) было также дешево. Тогда, если бы вы могли устранить один FLOP в пользу десятка обращений к памяти, вы сделали выигрыш. Если бы вы могли устранить один ФЛОП в пользу дюжины веток, вы сделали выигрыш. Таким образом, в прошлом имел смысл подсчитывать FLOP и не беспокоиться о ссылках на память и ветвях, потому что FLOPs сильно доминировали в времени выполнения, потому что они были индивидуально очень дорогими по сравнению с другими видами операций.

Совсем недавно ситуация изменилась. FLOPs стали очень дешевыми - любое современное ядро ​​Intel может выполнять около двух FLOP за один цикл (хотя разделение остается относительно дорогостоящим), а доступ к памяти и ветки сравнительно дороже: кэш L1 может стоить 3 или 4 цикла, выбор из стоимость основной памяти 150-200. Учитывая эту инверсию, , это уже не так, что устранение FLOP в пользу доступа к памяти приведет к усилению; на самом деле, это маловероятно. Точно так же часто дешевле "просто делать" FLOP, даже если это избыточно, а не решать, делать это или нет. Это почти полная противоположность ситуации 25 лет назад.

К сожалению, практика слепого FLOP-подсчета как абсолютной метрики алгоритмического достоинства сохранилась задолго до даты продажи. Современные научные вычисления гораздо важнее управления пропускной способностью памяти - попытки сохранить исполняемые модули, которые постоянно работают с FLOP, а не уменьшают количество FLOP. Ссылка на LINPACK (которая была, по существу, устарела LAPACK 20 лет назад), приводит меня к подозрению, что ваш работодатель, вероятно, имеет очень старую школу, которая не усвоила тот факт, что установление ожиданий в отношении производительности - это не просто вопрос, Решатель, который делает в два раза больше FLOP, может быть в двадцать раз быстрее, чем другой, если он имеет гораздо более выгодный шаблон доступа к памяти и расположение данных.

Результатом всего этого является то, что оценка производительности вычислительно интенсивного программного обеспечения стала намного сложнее, чем раньше. Тот факт, что FLOPs стал дешевым, чрезвычайно осложняется огромной изменчивостью затрат на операции памяти и ветки. Когда дело доходит до оценки алгоритмов, простой подсчет FLOP просто не информирует об общих ожиданиях производительности.

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

Это стоит посмотреть.

Ответ 5

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

Ответ 6

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

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

  • В большинстве случаев он находится в процессе вычисления производной и/или якобиана. Большая часть этого времени может идти в вызовы математических функций, таких как exp(), log() и sqrt(). Часто они повторяются с одинаковыми аргументами и могут быть замечены. (Массовое ускорение.)

  • Значительная часть времени затрачивается на расчет производных слишком много раз, потому что допуски интеграции более жесткие, чем необходимо. (Быстрее)

  • Если используется неявный алгоритм интеграции (например, DLSODE Gear), потому что уравнения считаются жесткими, скорее всего, это не так, и можно использовать что-то вроде Runge-Kutta. (DVERK). (Быстрее)

  • Возможно, алгоритм матрицы-экспоненты может быть использован, если модель линейна (DGPADM). Это большая победа как для производительности, так и для точности, и невосприимчива к жесткости. (Путь быстрее)

  • Чем выше уровень вызовов, тем может быть, что одни и те же интеграции выполняются несколько раз с несколько разными параметрами, чтобы определить градиент прямого или центрального разброса решения по этим параметрам. Если дифференциальные уравнения сами по себе дифференцируемы, то можно получить эти градиенты аналитически или увеличить уравнения с помощью уравнений чувствительности. Это не только намного быстрее, но и намного точнее, что может ускорить работу до уровня выше.

Вы можете смотреть на каждый уровень стека как возможность найти вещи для оптимизации, а ускорения будут сложными. Затем, когда вы переходите к мульти-процессору, считая его параллелизуемым, это должно обеспечить свой собственный мультипликативный фактор.

Итак, вернемся к FLOP. Вы можете попытаться максимизировать FLOPs / second, но также может быть намного более полезно минимизировать FLOPs / run путем оптимизации на всех уровнях стека. Во всяком случае, только их измерение почти ничего не говорит.

Ответ 7

Ваш работодатель прав.
Единственный способ измерить эффективность вашей программы Fortran (или любой другой программы, кстати) - проверить ее на стандартных тестах, если они существуют.

И, что касается FLOP, это означает "операции с плавающей запятой в секунду" - см. определение в Википедии.

Ответ 8

Я не думаю, что измерение FLOPS будет очень полезно.

Количество достигнутых FLOPS скажет вам, насколько ваш алгоритм поддерживает процессор, но не расскажет вам, насколько хорошо работает ваш алгоритм.

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

Я думаю, вам будет лучше смотреть на статистику "более высокого уровня", такую ​​как количество дифференциальных уравнений, решаемых за единицу времени (т.е. в конце концов, цель вашего алгоритма).

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