mirror of
https://github.com/Dr-Noob/cpufetch
synced 2025-08-28 12:57:54 +00:00
[v1.00] Skeleton for future support for other vector instructions in --accurate-pp
This commit is contained in:
parent
a5b321a966
commit
7226adb04d
1
.gitignore
vendored
1
.gitignore
vendored
@ -1 +1,2 @@
|
|||||||
cpufetch
|
cpufetch
|
||||||
|
*.o
|
||||||
|
20
Makefile
20
Makefile
@ -15,11 +15,12 @@ ifneq ($(OS),Windows_NT)
|
|||||||
ifeq ($(arch), $(filter $(arch), x86_64 amd64 i686))
|
ifeq ($(arch), $(filter $(arch), x86_64 amd64 i686))
|
||||||
SRC_DIR=src/x86/
|
SRC_DIR=src/x86/
|
||||||
SOURCE += $(COMMON_SRC) $(SRC_DIR)cpuid.c $(SRC_DIR)apic.c $(SRC_DIR)cpuid_asm.c $(SRC_DIR)uarch.c
|
SOURCE += $(COMMON_SRC) $(SRC_DIR)cpuid.c $(SRC_DIR)apic.c $(SRC_DIR)cpuid_asm.c $(SRC_DIR)uarch.c
|
||||||
HEADERS += $(COMMON_HDR) $(SRC_DIR)cpuid.h $(SRC_DIR)apic.h $(SRC_DIR)cpuid_asm.h $(SRC_DIR)uarch.h
|
HEADERS += $(COMMON_HDR) $(SRC_DIR)cpuid.h $(SRC_DIR)apic.h $(SRC_DIR)cpuid_asm.h $(SRC_DIR)uarch.h $(SRC_DIR)freq/freq.h
|
||||||
|
|
||||||
os := $(shell uname -s)
|
os := $(shell uname -s)
|
||||||
ifeq ($(os), Linux)
|
ifeq ($(os), Linux)
|
||||||
SOURCE += freq.o
|
SOURCE += $(SRC_DIR)freq/freq.c freq_nov.o freq_sse.o freq_avx.o freq_avx512.o
|
||||||
|
HEADERS += $(SRC_DIR)freq/freq.h
|
||||||
CFLAGS += -pthread
|
CFLAGS += -pthread
|
||||||
endif
|
endif
|
||||||
CFLAGS += -DARCH_X86 -std=c99 -fstack-protector-all
|
CFLAGS += -DARCH_X86 -std=c99 -fstack-protector-all
|
||||||
@ -69,8 +70,17 @@ static: $(OUTPUT)
|
|||||||
strict: CFLAGS += -O2 -Werror -fsanitize=undefined -D_FORTIFY_SOURCE=2
|
strict: CFLAGS += -O2 -Werror -fsanitize=undefined -D_FORTIFY_SOURCE=2
|
||||||
strict: $(OUTPUT)
|
strict: $(OUTPUT)
|
||||||
|
|
||||||
freq.o: Makefile $(SRC_DIR)freq.c $(SRC_DIR)freq.h
|
freq_nov.o: Makefile $(SRC_DIR)freq/freq_nov.c $(SRC_DIR)freq/freq_nov.h
|
||||||
$(CC) $(CFLAGS) $(SANITY_FLAGS) -c -mavx -mfma -pthread $(SRC_DIR)freq.c -o freq.o
|
$(CC) $(CFLAGS) $(SANITY_FLAGS) -c -pthread $(SRC_DIR)freq/freq_nov.c -o $@
|
||||||
|
|
||||||
|
freq_sse.o: Makefile $(SRC_DIR)freq/freq_sse.c $(SRC_DIR)freq/freq_sse.h
|
||||||
|
$(CC) $(CFLAGS) $(SANITY_FLAGS) -c -msse -pthread $(SRC_DIR)freq/freq_sse.c -o $@
|
||||||
|
|
||||||
|
freq_avx.o: Makefile $(SRC_DIR)freq/freq_avx.c $(SRC_DIR)freq/freq_avx.h
|
||||||
|
$(CC) $(CFLAGS) $(SANITY_FLAGS) -c -mavx -mfma -pthread $(SRC_DIR)freq/freq_avx.c -o $@
|
||||||
|
|
||||||
|
freq_avx512.o: Makefile $(SRC_DIR)freq/freq_avx512.c $(SRC_DIR)freq/freq_avx512.h
|
||||||
|
$(CC) $(CFLAGS) $(SANITY_FLAGS) -c -mavx512f -mfma -pthread $(SRC_DIR)freq/freq_avx512.c -o $@
|
||||||
|
|
||||||
$(OUTPUT): Makefile $(SOURCE) $(HEADERS)
|
$(OUTPUT): Makefile $(SOURCE) $(HEADERS)
|
||||||
$(CC) $(CFLAGS) $(SANITY_FLAGS) $(SOURCE) -o $(OUTPUT)
|
$(CC) $(CFLAGS) $(SANITY_FLAGS) $(SOURCE) -o $(OUTPUT)
|
||||||
@ -79,7 +89,7 @@ run: $(OUTPUT)
|
|||||||
./$(OUTPUT)
|
./$(OUTPUT)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
@rm -f $(OUTPUT) freq.o
|
@rm -f $(OUTPUT) *.o
|
||||||
|
|
||||||
install: $(OUTPUT)
|
install: $(OUTPUT)
|
||||||
install -Dm755 "cpufetch" "$(DESTDIR)$(PREFIX)/bin/cpufetch"
|
install -Dm755 "cpufetch" "$(DESTDIR)$(PREFIX)/bin/cpufetch"
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
#include "../common/args.h"
|
#include "../common/args.h"
|
||||||
#include "apic.h"
|
#include "apic.h"
|
||||||
#include "uarch.h"
|
#include "uarch.h"
|
||||||
#include "freq.h"
|
#include "freq/freq.h"
|
||||||
|
|
||||||
#define CPU_VENDOR_INTEL_STRING "GenuineIntel"
|
#define CPU_VENDOR_INTEL_STRING "GenuineIntel"
|
||||||
#define CPU_VENDOR_AMD_STRING "AuthenticAMD"
|
#define CPU_VENDOR_AMD_STRING "AuthenticAMD"
|
||||||
@ -194,8 +194,10 @@ int64_t get_peak_performance(struct cpuInfo* cpu, struct topology* topo, int64_t
|
|||||||
|
|
||||||
int64_t freq;
|
int64_t freq;
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
if(accurate_pp) freq = measure_avx_frequency(cpu);
|
if(accurate_pp)
|
||||||
else freq = max_freq;
|
freq = measure_frequency(cpu);
|
||||||
|
else
|
||||||
|
freq = max_freq;
|
||||||
#else
|
#else
|
||||||
// Silence compiler warning
|
// Silence compiler warning
|
||||||
(void)(accurate_pp);
|
(void)(accurate_pp);
|
||||||
|
@ -1,9 +0,0 @@
|
|||||||
#ifndef __FREQ__
|
|
||||||
#define __FREQ__
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "../common/cpu.h"
|
|
||||||
|
|
||||||
int64_t measure_avx_frequency(struct cpuInfo* cpu);
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,8 +1,13 @@
|
|||||||
#define _GNU_SOURCE
|
#define _GNU_SOURCE
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "../../common/global.h"
|
||||||
|
#include "../uarch.h"
|
||||||
#include "freq.h"
|
#include "freq.h"
|
||||||
#include "../common/global.h"
|
#include "freq_nov.h"
|
||||||
|
#include "freq_sse.h"
|
||||||
|
#include "freq_avx.h"
|
||||||
|
#include "freq_avx512.h"
|
||||||
|
|
||||||
#include <immintrin.h>
|
#include <immintrin.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -13,10 +18,8 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
|
||||||
#define MEASURE_TIME_SECONDS 5
|
|
||||||
#define MAX_NUMBER_THREADS 512
|
#define MAX_NUMBER_THREADS 512
|
||||||
#define FREQ_VECTOR_SIZE 1<<16
|
#define FREQ_VECTOR_SIZE 1<<16
|
||||||
#define LOOP_ITERS 100000000
|
|
||||||
|
|
||||||
struct freq_thread {
|
struct freq_thread {
|
||||||
bool end;
|
bool end;
|
||||||
@ -80,44 +83,38 @@ void* measure_freq(void *freq_ptr) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* compute_avx() {
|
int64_t measure_frequency(struct cpuInfo* cpu) {
|
||||||
bool end = false;
|
|
||||||
|
|
||||||
struct timeval begin, now;
|
|
||||||
|
|
||||||
__m256 a = _mm256_set1_ps(1.5);
|
|
||||||
__m256 b = _mm256_set1_ps(1.2);
|
|
||||||
__m256 c = _mm256_set1_ps(0.0);
|
|
||||||
|
|
||||||
gettimeofday(&begin, NULL);
|
|
||||||
while(!end) {
|
|
||||||
for(uint64_t i=0; i < LOOP_ITERS; i++) {
|
|
||||||
c = _mm256_fmadd_ps(a, b, c);
|
|
||||||
}
|
|
||||||
|
|
||||||
gettimeofday(&now, NULL);
|
|
||||||
double elapsed = (now.tv_sec - begin.tv_sec) + ((now.tv_usec - begin.tv_usec)/1000000.0);
|
|
||||||
end = elapsed >= (double) MEASURE_TIME_SECONDS;
|
|
||||||
}
|
|
||||||
|
|
||||||
FILE* fp = fopen("/dev/null", "w");
|
|
||||||
if(fp == NULL) {
|
|
||||||
printf("fopen: %s", strerror(errno));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
fprintf(fp, "%f", c[0]);
|
|
||||||
fclose(fp);
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
int64_t measure_avx_frequency(struct cpuInfo* cpu) {
|
|
||||||
int ret;
|
int ret;
|
||||||
|
int num_spaces;
|
||||||
struct freq_thread* freq_struct = malloc(sizeof(struct freq_thread));
|
struct freq_thread* freq_struct = malloc(sizeof(struct freq_thread));
|
||||||
freq_struct->end = false;
|
freq_struct->end = false;
|
||||||
freq_struct->measure = false;
|
freq_struct->measure = false;
|
||||||
|
|
||||||
|
void* (*compute_function)(void*);
|
||||||
|
|
||||||
|
if(cpu->feat->AVX512 && vpus_are_AVX512(cpu)) {
|
||||||
|
printf("cpufetch is measuring the AVX512 frequency...");
|
||||||
|
compute_function = compute_avx512;
|
||||||
|
num_spaces = 45;
|
||||||
|
}
|
||||||
|
else if(cpu->feat->AVX || cpu->feat->AVX2) {
|
||||||
|
printf("cpufetch is measuring the AVX frequency...");
|
||||||
|
compute_function = compute_avx;
|
||||||
|
num_spaces = 42;
|
||||||
|
}
|
||||||
|
else if(cpu->feat->SSE) {
|
||||||
|
printf("cpufetch is measuring the SSE frequency...");
|
||||||
|
compute_function = compute_sse;
|
||||||
|
num_spaces = 42;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf("cpufetch is measuring the frequency (no vector instructions)...");
|
||||||
|
compute_function = compute_nov;
|
||||||
|
num_spaces = 63;
|
||||||
|
}
|
||||||
|
|
||||||
|
fflush(stdout);
|
||||||
|
|
||||||
pthread_t freq_t;
|
pthread_t freq_t;
|
||||||
if(pthread_create(&freq_t, NULL, measure_freq, freq_struct)) {
|
if(pthread_create(&freq_t, NULL, measure_freq, freq_struct)) {
|
||||||
fprintf(stderr, "Error creating thread\n");
|
fprintf(stderr, "Error creating thread\n");
|
||||||
@ -126,7 +123,7 @@ int64_t measure_avx_frequency(struct cpuInfo* cpu) {
|
|||||||
|
|
||||||
pthread_t* compute_th = malloc(sizeof(pthread_t) * cpu->topo->total_cores);
|
pthread_t* compute_th = malloc(sizeof(pthread_t) * cpu->topo->total_cores);
|
||||||
for(int i=0; i < cpu->topo->total_cores; i++) {
|
for(int i=0; i < cpu->topo->total_cores; i++) {
|
||||||
ret = pthread_create(&compute_th[i], NULL, compute_avx, NULL);
|
ret = pthread_create(&compute_th[i], NULL, compute_function, NULL);
|
||||||
|
|
||||||
if(ret != 0) {
|
if(ret != 0) {
|
||||||
fprintf(stderr, "Error creating thread\n");
|
fprintf(stderr, "Error creating thread\n");
|
||||||
@ -134,9 +131,6 @@ int64_t measure_avx_frequency(struct cpuInfo* cpu) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("cpufetch is measuring AVX2 frequency...");
|
|
||||||
fflush(stdout);
|
|
||||||
|
|
||||||
sleep_ms(500);
|
sleep_ms(500);
|
||||||
freq_struct->measure = true;
|
freq_struct->measure = true;
|
||||||
|
|
||||||
@ -153,6 +147,6 @@ int64_t measure_avx_frequency(struct cpuInfo* cpu) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("\r ");
|
printf("\r%*c", num_spaces, ' ');
|
||||||
return freq_struct->freq;
|
return freq_struct->freq;
|
||||||
}
|
}
|
9
src/x86/freq/freq.h
Normal file
9
src/x86/freq/freq.h
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#ifndef __FREQ__
|
||||||
|
#define __FREQ__
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "../../common/cpu.h"
|
||||||
|
|
||||||
|
int64_t measure_frequency(struct cpuInfo* cpu);
|
||||||
|
|
||||||
|
#endif
|
46
src/x86/freq/freq_avx.c
Normal file
46
src/x86/freq/freq_avx.c
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <immintrin.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define MEASURE_TIME_SECONDS 5
|
||||||
|
#define LOOP_ITERS 100000000
|
||||||
|
|
||||||
|
void* compute_avx() {
|
||||||
|
bool end = false;
|
||||||
|
|
||||||
|
struct timeval begin, now;
|
||||||
|
|
||||||
|
__m256 a = _mm256_set1_ps(1.5);
|
||||||
|
__m256 b = _mm256_set1_ps(1.2);
|
||||||
|
__m256 c = _mm256_set1_ps(0.0);
|
||||||
|
|
||||||
|
gettimeofday(&begin, NULL);
|
||||||
|
while(!end) {
|
||||||
|
for(uint64_t i=0; i < LOOP_ITERS; i++) {
|
||||||
|
c = _mm256_fmadd_ps(a, b, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
gettimeofday(&now, NULL);
|
||||||
|
double elapsed = (now.tv_sec - begin.tv_sec) + ((now.tv_usec - begin.tv_usec)/1000000.0);
|
||||||
|
end = elapsed >= (double) MEASURE_TIME_SECONDS;
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE* fp = fopen("/dev/null", "w");
|
||||||
|
if(fp == NULL) {
|
||||||
|
printf("fopen: %s", strerror(errno));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
fprintf(fp, "%f", c[0]);
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
6
src/x86/freq/freq_avx.h
Normal file
6
src/x86/freq/freq_avx.h
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#ifndef __FREQ_AVX__
|
||||||
|
#define __FREQ_AVX__
|
||||||
|
|
||||||
|
void* compute_avx();
|
||||||
|
|
||||||
|
#endif
|
5
src/x86/freq/freq_avx512.c
Normal file
5
src/x86/freq/freq_avx512.c
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
void* compute_avx512() {
|
||||||
|
return NULL;
|
||||||
|
}
|
6
src/x86/freq/freq_avx512.h
Normal file
6
src/x86/freq/freq_avx512.h
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#ifndef __FREQ_AVX512__
|
||||||
|
#define __FREQ_AVX512__
|
||||||
|
|
||||||
|
void* compute_avx512();
|
||||||
|
|
||||||
|
#endif
|
5
src/x86/freq/freq_nov.c
Normal file
5
src/x86/freq/freq_nov.c
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
void* compute_nov() {
|
||||||
|
return NULL;
|
||||||
|
}
|
6
src/x86/freq/freq_nov.h
Normal file
6
src/x86/freq/freq_nov.h
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#ifndef __FREQ_NO_VECTOR__
|
||||||
|
#define __FREQ_NO_VECTOR__
|
||||||
|
|
||||||
|
void* compute_nov();
|
||||||
|
|
||||||
|
#endif
|
5
src/x86/freq/freq_sse.c
Normal file
5
src/x86/freq/freq_sse.c
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
void* compute_sse() {
|
||||||
|
return NULL;
|
||||||
|
}
|
6
src/x86/freq/freq_sse.h
Normal file
6
src/x86/freq/freq_sse.h
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#ifndef __FREQ_SSE__
|
||||||
|
#define __FREQ_SSE__
|
||||||
|
|
||||||
|
void* compute_sse();
|
||||||
|
|
||||||
|
#endif
|
Loading…
x
Reference in New Issue
Block a user