Алгоритм измерения частоты процессора сборки - PullRequest
15 голосов
/ 15 сентября 2008

Какие распространенные алгоритмы используются для измерения частоты процессора?

Ответы [ 9 ]

17 голосов
/ 15 сентября 2008

Процессоры Intel после Core Duo поддерживают два специфичных для модели регистра, называемых IA32_MPERF и IA32_APERF.
MPERF считает на максимальной частоте, которую поддерживает ЦП, в то время как APERF считает на фактической текущей частоте.

Фактическая частота определяется как:

freq = max_frequency * APERF / MPERF

Вы можете читать их с этим потоком

; read MPERF
mov ecx, 0xe7
rdmsr
mov mperf_var_lo, eax
mov mperf_var_hi, edx

; read APERF
mov ecx, 0xe8
rdmsr
mov aperf_var_lo, eax
mov aperf_var_hi, edx

но учтите, что rdmsr является привилегированной инструкцией и может выполняться только в кольце 0.

Я не знаю, предоставляет ли ОС интерфейс для их чтения, хотя они в основном используются для управления питанием, поэтому такой интерфейс может не предоставляться.

6 голосов
/ 23 сентября 2008

Я собираюсь встречаться с различными деталями в этом ответе, но какого черта ...

Мне пришлось решать эту проблему несколько лет назад на ПК под управлением Windows, поэтому я имел дело с процессорами Intel серии x86, такими как 486, Pentium и так далее. Стандартным алгоритмом в этой ситуации было выполнение длинного ряда инструкций DIVide, потому что они, как правило, являются наиболее привязанными к процессору одиночными инструкциями в наборе Intel. Таким образом, предварительная выборка из памяти и другие архитектурные проблемы не оказывают существенного влияния на время выполнения инструкции - очередь предварительной выборки всегда заполнена, а сама инструкция не затрагивает никакую другую память.

Вы бы рассчитывали время, используя часы с наивысшим разрешением, к которым вы могли бы получить доступ в среде, в которой вы работаете. (В моем случае я работал почти во время загрузки на ПК, совместимом, поэтому я непосредственно программировал микросхемы таймера на Материнская плата. Не рекомендуется в реальной ОС, обычно есть какой-то подходящий API для вызова в эти дни).

Основная проблема, с которой вам приходится сталкиваться - это разные типы процессоров. В то время Intel, AMD и некоторые мелкие производители, такие как Cyrix, делали процессоры x86. У каждой модели были свои рабочие характеристики по сравнению с инструкцией DIV. Моя функция синхронизации сборки будет просто возвращать количество тактовых циклов, выполненных определенным фиксированным количеством инструкций DIV, выполненных в узком цикле.

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

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

Здесь был трюк: я всегда ненавидел, когда вы запускаете утилиту, и она объявляет, что ваш процессор имеет частоту 99,8 МГц или что-то в этом роде. Ясно, что это было 100 МГц, и в измерении была только небольшая ошибка округления. В своей таблице я записал фактические скорости, которые продавались каждым поставщиком процессоров. Затем я бы использовал график фактического времени для оценки прогнозируемого времени для любой известной скорости. Но я бы построил таблицу точек вдоль линии, где время должно округляться до следующей скорости.

Другими словами, если 100 тиков для выполнения этого повторяющегося деления означают 500 МГц, а 200 тиков означают 250 МГц, то я построю таблицу, в которой будет сказано, что все, что ниже 150, будет 500 МГц, а что-нибудь выше, чем 250 МГц. , (Предполагая, что это были только две скорости, доступные от этого производителя чипов). Это было хорошо, потому что, даже если какой-то странный кусок программного обеспечения на ПК сбрасывал мои тайминги, конечный результат часто был бы мертвым.

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

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

4 голосов
/ 26 июня 2009

Один из способов на процессорах Intel x86, поскольку Pentium будет использовать две выборки команды RDTSC с циклом задержки известного времени задержки, например:

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

uint64_t rdtsc(void) {
    uint64_t result;
    __asm__ __volatile__ ("rdtsc" : "=A" (result));
    return result;
}

int main(void) {
    uint64_t ts0, ts1;    
    ts0 = rdtsc();
    sleep(1);
    ts1 = rdtsc();    
    printf("clock frequency = %llu\n", ts1 - ts0);
    return 0;
}

(на 32-битных платформах с GCC)

RDTSC доступен в кольце 3, если установлен флаг TSC в CR4, что является общим, но не гарантированным. Одним из недостатков этого метода является то, что он уязвим к изменениям масштабирования частоты, влияющим на результат, если они происходят внутри задержки. Чтобы снизить вероятность того, что вы сможете выполнить код, который будет загружать ЦП и постоянно опрашивать системное время, чтобы увидеть, истек ли период задержки, чтобы поддерживать ЦП в максимально возможной частоте.

2 голосов
/ 05 августа 2011

Я использую следующий (псевдо) алгоритм:

basetime=time();    /* time returns seconds */

while (time()==basetime);
stclk=rdtsc();    /* rdtsc is an assembly instruction */

basetime=time();
while (time()==basetime
endclk=rdtsc();

nclks=encdclk-stclk;

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

Все ПК содержат устройство PIT (программируемый интервальный таймер), которое содержит счетчики, которые (использовались) для последовательных портов и системных часов. Питался с частотой 1193182 Гц. Счетчик системных часов был установлен на самое высокое значение обратного отсчета (65536), в результате чего частота тактов системных часов составила 1193182/65536 => 18,2065 Гц или один раз каждые 54,925 миллисекунд.

Следовательно, число тактов, необходимое для приращения часов к следующей секунде, будет зависеть. Обычно требуется 18 тиков, а иногда 19. Это можно сделать, выполнив алгоритм (см. Выше) дважды и сохранив результаты. Два результата будут либо эквивалентны двум последовательностям по 18 тиков, либо одному из 18 и одному 19. Два 19 подряд не появятся. Таким образом, взяв меньшее из двух результатов, вы получите 18 тиковых секунд. Откорректируйте этот результат, умножив на 18,2065 и поделив на 18,0 или, используя целочисленную арифметику, умножьте на 182065, добавьте 90000 и разделите на 180000. 90000 - это половина от 180000 и используется для округления. Если вы выбираете вычисление с целочисленным маршрутом, убедитесь, что вы используете 64-битное умножение и деление.

Теперь у вас будет тактовая частота процессора x в Гц, которую можно преобразовать в кГц ((x + 500) / 1000) или МГц ((x + 5000000) / 1000000). 500 и 500000 составляют половину от 1000 и 1000000 соответственно и предназначены для округления. Для расчета МГц не используйте значение кГц, поскольку могут возникнуть проблемы с округлением. Используйте значение Гц и второй алгоритм.

1 голос
/ 16 октября 2015

Один из вариантов - определить частоту процессора, запустив код с известными инструкциями для цикла

Эта функциональность содержится в 7zip, начиная с версии 9.20, я думаю.

> 7z b
7-Zip 9.38 beta  Copyright (c) 1999-2014 Igor Pavlov  2015-01-03

CPU Freq:  4266  4000  4266  4000  2723  4129  3261  3644  3362

Окончательное число должно быть правильным (и на моем ПК и многих других я нашел его достаточно правильным - тест выполняется очень быстро, поэтому турбо может не сработать, а серверы установлены в режимах Balanced / Power Save). скорее всего, показания около 1 Гц)

Исходный код: GitHub (Официальный источник загружен с 7-zip.org)

Самая значительная часть:

#define YY1 sum += val; sum ^= val;
#define YY3 YY1 YY1 YY1 YY1
#define YY5 YY3 YY3 YY3 YY3
#define YY7 YY5 YY5 YY5 YY5
static const UInt32 kNumFreqCommands = 128;

EXTERN_C_BEGIN

static UInt32 CountCpuFreq(UInt32 sum, UInt32 num, UInt32 val)
{
  for (UInt32 i = 0; i < num; i++)
  {
    YY7
  }
  return sum;
}

EXTERN_C_END
1 голос
/ 27 марта 2009

«lmbench» предоставляет частотный алгоритм процессора, переносимый для другой архитектуры.

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

этот метод всегда должен работать, когда мы можем получить циклы с относительно простым числом циклов.

http://www.bitmover.com/lmbench/

1 голос
/ 15 сентября 2008

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

Частоты процессора также являются переменными в зависимости от предлагаемой нагрузки и / или температуры. Тот факт, что процессор в настоящее время работает на частоте 800 МГц, не означает, что он всегда будет работать на частоте 800 МГц, он может увеличивать или уменьшать при необходимости.

Если вам действительно нужно знать тактовую частоту, она должна быть передана в качестве параметра. ЭСППЗУ на плате будет обеспечивать базовую частоту, и если тактовая частота может меняться, вам понадобится прочитать регистры состояния питания ЦП (или сделать вызов ОС), чтобы узнать частоту в этот момент.

С учетом всего вышесказанного, могут быть и другие способы выполнить то, что вы пытаетесь сделать. Например, если вы хотите выполнить высокоточные измерения того, сколько времени занимает конкретный путь кода, ЦП, скорее всего, имеет счетчики производительности, работающие с фиксированной частотой, которые являются лучшим показателем времени настенного времени, чем чтение регистра подсчета тиков.

0 голосов
/ 07 января 2009

Быстрый Google на AMD и Intel показывает, что CPUID должен дать вам доступ к максимальной частоте CPU.

0 голосов
/ 15 сентября 2008

Я не уверен, зачем вам нужна сборка для этого. Если вы работаете на компьютере с файловой системой / proc, то выполните:

> cat /proc/cpuinfo

может дать вам то, что вам нужно.

...