Измерение тактовой частоты процессора

Я пытаюсь измерить скорость процессора. Я не уверен, насколько точен мой метод. По сути, я попробовал пустой цикл for со значениями типа UINT_MAX, но программа быстро завершилась, поэтому я попробовал UINT_MAX * 3 и так далее...

Затем я понял, что компилятор оптимизирует цикл, поэтому я добавил переменную volatile, чтобы предотвратить оптимизацию. Выполнение следующей программы занимает примерно 1,5 секунды. Я хочу знать, насколько точен этот алгоритм измерения тактовой частоты. Кроме того, как узнать, сколько ядер задействовано в процессе?

#include <iostream>
#include <limits.h>
#include <time.h>

using namespace std;

int main(void)
{
    volatile int v_obj = 0;
    unsigned long A, B = 0, C = UINT32_MAX;

    clock_t t1, t2;
    t1 = clock();

    for (A = 0; A < C; A++) {
        (void)v_obj;
    }
    t2 = clock();
    std::cout << (double)(t2 - t1) / CLOCKS_PER_SEC << std::endl;

    double t = (double)(t2 - t1) / CLOCKS_PER_SEC;
    unsigned long clock_speed = (unsigned long)(C / t);

    std::cout << "Clock speed : " << clock_speed << std::endl;
    return 0;
}

person Community    schedule 18.06.2016    source источник
comment
Поскольку современные процессоры имеют переменную тактовую частоту и несколько ядер; запуск такого теста будет измерять только максимальную тактовую частоту 1 ядра.   -  person Richard Critten    schedule 18.06.2016
comment
Поместив туда volatile, вы замедлили свой цикл до скорости памяти, превзойдя свою цель измерения скорости процессора.   -  person David Schwartz    schedule 19.06.2016
comment
@DavidSchwartz Итак, как именно вы предотвращаете оптимизацию?   -  person    schedule 19.06.2016
comment
@layzak Весь этот метод измерения тактовой частоты процессора не имеет смысла. Не ремонтируй, выброси.   -  person David Schwartz    schedule 20.06.2016


Ответы (2)


Это вообще не измеряет тактовую частоту, а измеряет, сколько итераций цикла можно выполнить в секунду. Нет правила, согласно которому за такт будет выполняться одна итерация. Возможно так оно и есть, и вы, возможно, действительно обнаружили, что это так - конечно, с оптимизированным кодом и разумным процессором бесполезный цикл не должен работать намного медленнее, чем это. Однако он может работать на половинной скорости, некоторые процессоры не могут удалять более 1 взятой ветки каждые 2 цикла. А на эзотерические цели все ставки сняты.

Так что нет, это не измеряет тактовые циклы, кроме как случайно. В общем, чрезвычайно сложно получить эмпирическую тактовую частоту (вы можете спросить свою ОС, какова, по ее мнению, максимальная тактовая частота и текущая тактовая частота, см. ниже), потому что

  1. Если вы измеряете, сколько времени на настенных часах занимает цикл, вы должны знать (хотя бы приблизительно) количество циклов на итерацию. Это достаточно серьезная проблема в ассемблере, требующая довольно подробного знания ожидаемых микроархитектур (может быть, длинная цепочка зависимых инструкций, каждая из которых может разумно выполнять только 1 цикл, например add eax, 1? достаточно длинная цепочка, чтобы различия в пропускной способности теста/ветви стали небольшими достаточно, чтобы игнорировать), поэтому очевидно, что все, что вы там делаете, не является переносимым, и в него будут встроены предположения, которые могут стать ложными (на самом деле есть другой ответ на SO, который делает это и предполагает, что addps имеет задержку 3, что не так) t больше на Skylake и не было на старых AMD). В Си? Сдавайся сейчас. Компилятор может запускать какой-то генератор случайного кода, и полагаться на его разумность — все равно, что делать то же самое с медведем. Гадать о количестве циклов на итерацию кода, который вы не контролируете и даже не знаете, просто глупо. Если это только на вашей собственной машине, вы можете проверить код, но тогда вы можете просто проверить тактовую частоту вручную, так что ..

  2. Если вы измерите количество тактов, прошедших за заданное время настенных часов... но это сложно. Потому что rdtsc не измеряет тактовые циклы (больше нет), и ничто другое не приближается. Вы можете измерить что-то, но с масштабированием частоты и турборежимом это, как правило, не будет реальным тактовым циклом. Вы можете получить фактические такты от счетчика производительности, но вы не можете сделать это из пользовательского режима. Очевидно, что любой способ, которым вы пытаетесь это сделать, не является переносимым, потому что вы не можете переносимо запросить количество прошедших тактов.

Так что, если вы делаете это для фактической информации, а не просто для того, чтобы бездельничать, вам, вероятно, следует просто спросить ОС. Для Windows запросите WMI для CurrentClockSpeed ​​или MaxClockSpeed, в зависимости от того, что вы хотите. В Linux есть вещи в /proc/cpuinfo. Все еще не переносимый, но тогда нет решения.

Что касается

как узнать, сколько ядер задействовано в процессе?

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

person harold    schedule 18.06.2016
comment
В Linux есть команда perf stat ./program, которая будет отслеживать и сообщать о средней тактовой частоте процессора для любой программы ./program (как X.XX GHz). Он использует Hardware PMU - счетчики производительности для подсчета реальных циклов процессора (не tsc), используемых для запуска программы, а также ведет учет времени (программное событие Task-Clock). Реальные счетчики часов могут быть доступны через perf_events linux API или с помощью некоторых переносимых библиотек, таких как PAPI, непосредственно из пользовательского пространства. - person osgx; 19.06.2016

Хороший оптимизатор может удалить цикл, так как

for (A = 0; A < C; A++) {
    (void)v_obj;
}

оказывает такое же влияние на состояние программы, как;

A = C;

Таким образом, оптимизатор может полностью раскрутить ваш цикл.

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

person Soren    schedule 18.06.2016
comment
Не пугает ли компилятор volatile несколько? Э: видимо нет - person harold; 19.06.2016