Понимание пропускной способности реализации simd sum x86

У меня есть следующий цикл в asm:

.LBB5_5:
 vaddpd  ymm0, ymm0, ymmword, ptr, [rdi, +, 8*rcx]
 vaddpd  ymm1, ymm1, ymmword, ptr, [rdi, +, 8*rcx, +, 32]
 vaddpd  ymm2, ymm2, ymmword, ptr, [rdi, +, 8*rcx, +, 64]
 vaddpd  ymm3, ymm3, ymmword, ptr, [rdi, +, 8*rcx, +, 96]
 add     rcx, 16
 cmp     rax, rcx
 jne     .LBB5_5

Это часть более крупной функции, которая вычисляет сумму массива [f64] в Rust.

Я сравнил этот код с набором критериев и обнаружил, что 1 000 000 000 двойные операции занимают 200 000 000 циклов на моем процессоре Rocket Lake (i7 11700K).

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

Мои измерения показывают, что он делает 5 прибавок за цикл. (Для измерения используется инструкция RDTSC, я не уверен, что это может быть проблематично)

В основном я хочу понять, что происходит, и проверить, насколько хорошо я понимаю конвейер ЦП.

Выложенный вами код не совсем корректен из-за лишних запятых. В инструкциях 4 vpaddpd используются отдельные аккумуляторы, что означает, что они могут выполняться параллельно. Учитывая, что в Rocket Lake vpaddpd обратная пропускная способность равна 0,5, это означает, что за такт может запускаться до двух таких дополнений. В зависимости от продолжительности цикла и от того, находятся ли исходные данные в кэше, пропускная способность памяти может быть здесь ограничивающим фактором.

Andrey Semashev 27.03.2024 13:07

@AndreySemachev Это всего лишь представление cargo asm, это не петля ручной работы. Я знаю, что эти 4 инструкции можно выполнять параллельно, но это должно дать мне только 4 раза по 4 удвоения за 4 такта. Я наблюдаю более быстрое исполнение

Unlikus 27.03.2024 13:11
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
2
79
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

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

Ваш процессор имеет базовую частоту 3,6 ГГц и максимальную турбо-частоту 5,00 ГГц. Если вы проведете короткий тест, ваш процессор будет работать на турбо-частоте, однако счетчик, измеренный с помощью RDTSC, все равно будет работать на базовой частоте.

Это действительно была проблема. Когда я отключаю турбо, я получаю 260 000 000 циклов, что совместимо с 4 добавлениями за цикл.

Unlikus 27.03.2024 13:16

RDTSC по-прежнему работает на базовой частоте. - Или какая-то близкая к ней частота, напр. 4008 МГц на моем i7-6700k (базовая частота 4 ГГц, повышение 4,2 ГГц). Или на некоторых процессорах, даже близких к базовой частоте, например. некоторые мобильные процессоры Ice Lake, поддерживающие TDP-up и TDP-down. Как получить количество циклов процессора в x86_64 из C++?. Хм, интересно, как это работает на Alder Lake с E-ядрами и P-ядрами? Предположительно, TSC по-прежнему синхронизируются по всем ядрам, как типичные многоядерные процессоры, поэтому один набор ядер будет иметь TSC, который практически не связан с тактовой частотой его ядра.

Peter Cordes 28.03.2024 07:11

Другие вопросы по теме