[LINUX] Verwenden Sie Invariant TSC

Einführung

Intel-CPUs haben einen Zähler, der bei konstantem Takt hochzählt. Es heißt Invariant TSC (Time Stamp Counter). Ich werde erklären, wie man das benutzt. Der Beispielcode wird mit gcc von MINGW64 erstellt.

Invariant TSC available Flag Mit der Anweisung CPUID können Sie überprüfen, ob die invariante TSC verfügbar ist. Setzen Sie das eax-Register auf 0x80000007, um den Befehl cpuid auszuführen. Bit 08 von edx ist dieses Flag.

code 1 Zeigt den Beispielcode zum Lesen des verfügbaren unveränderlichen TSC-Flags an.

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 Invariante TSC ist eine 64-Bit-Ganzzahl ohne Vorzeichen. Es kann durch RDTSCP-Anweisung gelesen werden.

code 2 Zeigt den Code an, der die TSC liest und anzeigt, wenn die EINGABETASTE gedrückt wird. Sie können die TSC-Frequenz schätzen, indem Sie in regelmäßigen Abständen die ENTER-Taste drücken.

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;
}

Versuchen Sie, die ENTER-Taste im Abstand von 10 Sekunden zu drücken, während Sie auf Ihre Uhr schauen. Der Unterschied in der TSC beträgt 22 * 10 ^ 9. In Sekunden umgerechnet sind es 2,2 GHz. Die CPU, die ich lief, war Intel (R) Core (TM) i5-5200U CPU bei 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 Maschinenspezifische Register (MSRs) müssen gelesen werden, um die korrekte invariante TSC-Frequenz zu erhalten. Es ist etwas schwierig, da Sie sich im privilegierten Modus befinden müssen, um MSRs lesen zu können. Daher wurde in Code 2 die Frequenz geschätzt, indem in regelmäßigen Abständen invariante TSC-Messungen durchgeführt wurden.

Die invariante TSC-Frequenz beträgt 0xCE 15: 8 Bit ** Maximales Nicht-Turbo-Verhältnis ** multipliziert mit 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 Sie können MSRs mit CPU-Z lesen. Wählen Sie Bericht als .TXT speichern aus, um ihn in einer Datei zu speichern.

1.png

Der Text enthält die folgende Zeile:

Max non-turbo ratio 22x

Daher wurde festgestellt, dass die invariante TSC-Frequenz dieser CPU 22 × 100 MHz = 2,2 GHz beträgt.

Linux Verwenden Sie unter Linux rdmsr, um MSRs zu lesen.

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. Daher wurde festgestellt, dass die invariante TSC-Frequenz dieser CPU 34 x 100 MHz = 3,4 GHz beträgt.

Recommended Posts

Verwenden Sie Invariant TSC
Verwenden Sie DeepLabCut
Verwenden Sie pycscope
Verwenden Sie Sammlungen
Verwenden Sie: Django-MySQL
Verwenden Sie Pylements.rb
Verwenden Sie Numpy
Verwenden Sie Pandas-Ply
Verwenden Sie GitPython
Verwenden Sie Miniconda