Pull to refresh
1
0
Сергей Прейс @Loginin

Разработчик

Send message
Это еще мелочи:
Я: Болталка
Алиса: Свиноматка


В Дзене рядом ссылка на эту статью и реклама Яндекс.Директа
Заработал на машину за вечер
Урвал 74 миллиона за вечер…
С ссылккой на сайт прикидывающийся Газета.ру:
http://power4you.ru/?utm_source=yandex&utm_medium=cpc&utm_campaign=27911146&utm_content=4313928277&utm_term=заработок

Какая-то странная борьба получается.
Ну да, неточно выразился, спасибо. latency для инструкции — это время её исполнения от постановки на исполнение до выработки результата.
А как получился 'NoNRePReSeNTaTiONaL' — нет же элемента L?
Из-за конвейерного исполнения темп поступления/завершения инструкций (throughput) может быть выше чем скорость их исполнения (latency). БОльшая часть инструкций в современных процессорах может стартовать/завершаться с темпом одна инструкция за такт на порт и именно количество завершенных инструкций показывает IPC. Но есть и медленные инструкции, которые не могут стартовать каждый такт на одном порту, а также бывает, что внутреннего параллелизма вычислений не хватает для загрузки конвейера (свежие инструкции ждут результатов от исполняющихся). Тогда длительность исполнения инструкций начинает играть роль и IPC закономерно падает.
Выводы статьи кажутся странными.
1. IPC не может точно указывать во что упёрлась программа — есть разные причины простоя и на разветвлённом плохо предсказываемом коде можно получить IPC < 1 даже имея все данные в кэше. Низкий IPC указывает на архитектурные простои любой природы (неверная спекуляция, нехватка ресурсов, задержки в доставке операндов и т.п.).

2. На IPC не имеет смысла смотреть пока нет уверенности, что программа достаточно хорошо оптимизирована — на ранних этапах оптимизации макро-эффекты (неэффективные последовательности инструкций в силу неудачного алгоритма, размещения данных или кодирования) имеют гораздо больший эффект. Более удачная организация алгоритма и структур данных может дать как сокращение числа инструкций, так и снижение нагрузки на память (за счёт более эффективного кэширования) и может повлиять на IPC в любую сторону. Основной метрикой при оптимизации должны быть попугаи специфичные для приложения, а IPC лишь вспомогательный инструмент не очень полезный сам по себе (см.3).

3. Не все IPC одинаково полезны — в AVX2 одна F32 инструкция FMA делает 16 операций, но в IPC она учтётся как одна инструкция. Цикл её заменяющий запросто может дать более высокий IPC, но FLOPS (попугаи приложения Linpack) от него будет гораздо меньше. Да и в более простом примере movl (%rax), %rbx, add %rbx, %rdx — это 2 инструкции, а add (%rax), %rdx — одна, но более высокий IPC для первого случая (скорее всего время выполнения для обоих случаев будет одинаковым, но инструкций в первом случае больше) не транслируется в более высокую производительность.

Оптимизация на уровне IPC всегда должна делаться с оглядкой на исполняемый код (ну может кроме случая, когда цель — это повысить температуру в помещении за счёт загрузки процессора).
Для классических матричных и векторных операций есть Eigen, но грамотно использованный SIMD позволяет ускорить широкий спектр алгоритмов не завязанных на матрицы и «длинные» векторы. Сюда относятся и трассировка лучей и модели соударений (NBody) и квантовая хромодинамика и много чего ещё со сложно-структурированными данными и/или глубокими гнездами циклов. В многомерных циклах далеко не все данные SIMD — часть обязательно будет скалярной. Это верно даже для умножения матриц. А для для массивов структурированных данных a*b — уже вообще не очевидная операция (даже если эта структура всего лишь комплексное число).

SPMD как раз про это. Его сильнейшая сторона — это совмещение скалярных(uniform) и SIMD(varying) данных в структурах и алгоритмах включая грамотный подход к обработке ветвлений/маскирований. Но SPMD — это язык в языке с кучей ограничений равно как и OpenMP/SIMD. Есть одно похожее решение — Intel SDLТ. Это полностью шаблонная С++ библиотека, но к сожалению проприетарная потому как опирается на мощь векторизатора в ICC. Она тоже про это же но только со стороны данных, ей нужен мощный векторизатор чтобы получить хороший код.

На самом деле в комитете обсуждается ряд предложений в Parallelism TS2 ровно на эти темы:
— Более низкоуровневый вариант — это P0214R3. С короткими векторами и операциями почти как в SPMD.
— Более высокоуровневый — это P0076R1 + P0075R1 + P0601R0. Алгоритмы + вызовы функций.
Все они сейчас в разной степени проработанности, близости к (моему) идеалу и продвижения к стандарту, но ни одно из них не вошло в C++17, что обидно и ровно на это я посетовал в своём комментарии.
SIMD очень хочется нормальный. И в алгоритмах (желательно с поддержкой функций как в OpenMP, но как минимум simd execution mdoel для алгоритмов), так и на уровне типов данных (желательно с поддержкой адаптирующейся ширины, чтобы не делать Vec<Int, 4> для SSE, Vec<Int, 8> для AVX2 и Vec<Int, 16> для AVX512).

Information

Rating
Does not participate
Location
Россия
Registered
Activity