Есть ли способ измерить задержку нескольких нагрузок параллельно в x86 (с использованием RDTSCP или RDTSC) без сериализации?

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

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

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

1. rdtscp
2. load-1
3. rdtscp

4. rdtscp 
5. load-2
6. rdtscp

В приведенном выше коде свойство упорядочивания rdtscp в Intel x86 сериализует выполнение load-1 и load-2 в соответствии с моим тестированием (т.е. load-2 выдается в систему памяти только после загрузки -1 завершает выполнение). В результате приведенный выше код не использует доступную пропускную способность памяти. В идеале я хотел бы обеспечить максимальную пропускную способность для нагрузок, измеряя при этом задержку каждой загрузки независимо.

Есть ли способ измерить задержку load-1 и load-2, позволяя им выполняться параллельно?

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


person gururaj    schedule 28.01.2020    source источник
comment
Описание rdtsc предполагает, что rdtscp ждет, пока все предыдущие инструкции не будут выполнены и все предыдущие загрузки станут глобально видимыми . Таким образом, я не могу использовать его напрямую.   -  person gururaj    schedule 29.01.2020
comment
В предыдущем сообщении Stackoverflow высказывалось мнение, что rdtscp применяет Полноценное поведение: любые инструкции загрузки по обе стороны от вызова rdtscp не переупорядочиваются вокруг него. Я наблюдал подобное поведение в своем тестировании, которое вызвало этот вопрос.   -  person gururaj    schedule 29.01.2020


Ответы (1)


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


Существуют события perf для mem_trans_retired.load_latency_gt_32 и так далее для степеней 2 от 4 до 512. Для этого вы можете запрограммировать счетчики и rdpmc. Но он не скажет вам, какая нагрузка какое событие вызвала.

Учитывая вашу общую цель, вы можете использовать эти счетчики с perf stat или perf record, чтобы получить среднее значение для всего цикла, когда (одноядерная) полоса пропускания памяти исчерпана.

Обратите внимание, что они учитывают задержку от первой отправки (до порта загрузки), а не проблемы с серверной частью.

person Peter Cordes    schedule 28.01.2020