Почему бы не взять один такт - PullRequest
0 голосов
/ 12 января 2020

Я написал базовый c код, чтобы узнать количество тактов, занятых nop. Мы знаем, что nop занимает один тактовый цикл.

#include <stdio.h>
#include <string.h>
#include <stdint.h>


int main(void)
{
    uint32_t low1, low2, high1, high2;
    uint64_t timestamp1, timestamp2;
    asm volatile ("rdtsc" : "=a"(low1), "=d"(high1));
    asm("nop");
    asm volatile ("rdtsc" : "=a"(low2), "=d"(high2));
    timestamp1 = ((uint64_t)high1 << 32) | low1; 
    timestamp2 = ((uint64_t)high2 << 32) | low2; 
    printf("Diff:%lu\n", timestamp2 - timestamp1);
    return 0;
}

Но результат не равен 1.

Иногда это 14 или 16.

Могу ли я узнать причину этого , Я что-то упускаю

1 Ответ

1 голос
/ 12 января 2020

Мы знаем, что nop занимает один тактовый цикл.

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

A NOP не имеет микроопераций - он просто отбрасывается интерфейсом. Это не стоит 1 цикл.

Но результат не равен 1.

Вероятно, требуется 14 или 16 циклов для инструкций, которые генерирует компилятор, чтобы справиться с выходы первого rdtsc, затем готовятся ко второму rdtsc, затем ко второму rdtsc.

Обратите внимание, что rdtsc, вероятно, считает циклы таймера с фиксированной частотой, который не имеет ничего Текущая (переменная) тактовая частота процессора; поэтому 14 или 16 «временных циклов» могут быть (например, 7 или 8 циклов ЦП.

...