[LINUX] Utiliser le TSC invariant

introduction

Les processeurs Intel ont un compteur qui compte à une horloge constante. Il est appelé Invariant TSC (Time Stamp Counter). Je vais vous expliquer comment l'utiliser. L'exemple de code est créé avec gcc de MINGW64.

Invariant TSC available Flag Vous pouvez vérifier si l'invariant TSC est disponible en utilisant l'instruction CPUID. Définissez le registre eax sur 0x80000007 pour exécuter l'instruction cpuid. Le bit 08 d'edx est ce drapeau.

code 1 Affiche l'exemple de code pour lire l'indicateur disponible TSC invariant.

makefile


CFLAGS=-I. -Wall -Werror -O2
INCS=
OBJS=test.o
LIBS=
TARGET=test

all: $(TARGET)

%.o: %.c $(INCS)
	$(CC) $(CFLAGS) -c -o $@ $<

%.o: %.s $(INCS)
	$(CC) $(CFLAGS) -c -o $@ $<

$(TARGET): $(OBJS)
	$(CC) $(CFLAGS) -o $@ $^ $(LIBS)

clean:
	rm -rf $(TARGET) *.o

test.s


# rcx(1st) rdx(2nd) r8(3rd) r9(4th)
    .globl  main
main:
    subq    $40, %rsp
    call    __main
    
    # EDX Bit 08: Invariant TSC available if 1.
    movl    $0x80000007, %eax
    cpuid
    # printf
    leaq    s0, %rcx   # 1st
    movl    %edx, %edx # 2nd
    call    printf
    
    xorl    %eax, %eax
    addq    $40, %rsp
    ret
    .section .rodata
s0: .asciz "cpuid 0x80000007 edx : 0x%08X \n"

console


$ make && ./test.exe
cpuid 0x80000007 edx : 0x00000100

RDTSCP instruction Invariant TSC est un entier 64 bits non signé. Il peut être lu par l'instruction RDTSCP.

code 2 Indique le code qui lit et affiche le TSC lorsque la touche ENTER est enfoncée. Vous pouvez estimer la fréquence TSC en appuyant sur la touche ENTER à intervalles réguliers.

test.c


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

static inline uint64_t RDTSCP();
static void print_tsc();

int main(int argc, char* argv[])
{
  while(1) {
    char buf[4];
    print_tsc();
    printf("press ENTER key.");
    fflush(stdout);
    fgets(buf, 4, stdin);
  }
  
  return 0;
}

static inline uint64_t RDTSCP()
{
  uint32_t hi, lo, aux;
  __asm__ volatile("rdtscp" : "=a" (lo), "=d" (hi), "=c" (aux));
  return ((uint64_t)hi << 32) | lo;
}

static void print_tsc()
{
  #define MAXU64 (0xFFFFFFFFFFFFFFFF)
  static uint64_t prev = MAXU64;
  uint64_t tsc, diff = 0;
  
  tsc = RDTSCP();
  if (prev != MAXU64) {
    diff = tsc - prev;
    printf("tsc=%" PRIu64 " diff=%" PRIu64 "\n", tsc, diff);
  } else {
    printf("tsc=%" PRIu64 "\n", tsc);
  }
  prev = tsc;
}

Essayez d'appuyer sur la touche ENTRÉE toutes les 10 secondes tout en regardant votre montre. La différence de TSC est de 22 * 10 ^ 9. Converti en secondes, il est de 2,2 GHz. Le processeur que j'ai utilisé était un processeur Intel (R) Core (TM) i5-5200U à 2,20 GHz.

console


$ make && ./test.exe
tsc=141732173016637
press ENTER key.
tsc=141752243551743 diff=20070535106
press ENTER key.
tsc=141774064869318 diff=21821317575
press ENTER key.
tsc=141796080991589 diff=22016122271
press ENTER key.

Invariant TSC Frequency Les registres spécifiques à la machine (MSR) doivent être lus pour obtenir la fréquence TSC invariante correcte. C'est un peu difficile car vous devez être en mode privilégié pour lire les MSR. Par conséquent, dans le code 2, la fréquence a été estimée en mesurant le TSC invariant à intervalles réguliers.

La fréquence TSC invariante est 0xCE 15: 8 bits ** Rapport non turbo maximal ** multiplié par 100 MHz.

0xCE 15:8 bit Maximum Non-Turbo Ratio (R/O) The is the ratio of the frequency that invariant TSC runs at. Frequency = ratio * 100 MHz.

Windows Vous pouvez lire les MSR avec CPU-Z. Sélectionnez Enregistrer le rapport sous .TXT pour enregistrer dans un fichier.

1.png

Il y a la ligne suivante dans le texte:

Max non-turbo ratio 22x

Par conséquent, il a été constaté que la fréquence TSC invariante de ce processeur est de 22x100 MHz = 2,2 GHz.

Linux Sous Linux, utilisez rdmsr pour lire les MSR.

console


$ cat /proc/cpuinfo | grep "model name"
model name      : Intel(R) Core(TM) i7-6700 CPU @ 3.40GHz
$ sudo apt-get install msr-tools
$ sudo modprobe msr
$ sudo rdmsr 0xce
80838f1012200

0x22 = 34. Par conséquent, il a été constaté que la fréquence TSC invariante de ce processeur est de 34x100 MHz = 3,4 GHz.

Recommended Posts

Utiliser le TSC invariant
Utilisez DeepLabCut
Utiliser pycscope
Utilisez des collections.
Utilisation: Django-MySQL
Utilisez Pygments.rb
Utilisez Numpy
Utilisez pandas-ply
Utilisez GitPython
Utiliser Miniconda