執行 make,會編譯並紀錄測試結果,輸出檔案名稱為 compare.png
** 注意!! dmesg 中的紀錄會被刪除,若有需要請事先備份 **
#include <linux/init.h> | |
#include <linux/module.h> | |
#include <linux/random.h> | |
#pragma GCC optimize ("O0") | |
#define MAX_ITER 1000000 | |
#define ADD_ONCE 1000 | |
MODULE_DESCRIPTION("Kernel module with floating point operation"); | |
MODULE_LICENSE("Dual MIT/GPL"); | |
static int __init float_init(void) { | |
long long int start, end; | |
for (int j=0; j<MAX_ITER; j+=ADD_ONCE) { | |
#ifdef INTEGER_OP | |
int a, b, c; | |
get_random_bytes(&a, sizeof(a)); | |
get_random_bytes(&b, sizeof(b)); | |
#else | |
int x, y; | |
float a, b, c; | |
get_random_bytes(&x, sizeof(x)); | |
get_random_bytes(&y, sizeof(y)); | |
a = (float)x + (float)1.0/b; | |
get_random_bytes(&x, sizeof(x)); | |
get_random_bytes(&y, sizeof(y)); | |
b = (float)x + (float)1.0/b; | |
#endif | |
start = ktime_get_ns(); | |
#ifdef INTEGER_OP | |
for (int i=0; i < j; ++i) { | |
c = a*b; | |
} | |
#else | |
for (int i=0; i < j; ++i) { | |
c = a*b; | |
} | |
#endif | |
end = ktime_get_ns(); | |
printk(KERN_DEBUG "%d %lld", j, end-start); | |
} | |
return 0; | |
} | |
static void __exit float_exit(void) { | |
} | |
module_init(float_init); | |
module_exit(float_exit); |
PWD := $(shell pwd) | |
KDIR = /usr/src/linux-headers-$(shell uname -r)/ | |
MODULE_NAME = floating | |
obj-m := $(MODULE_NAME).o | |
ccflags-y := -std=gnu99 -Wno-declaration-after-statement -mhard-float | |
all: clean integer_ver float_ver | |
gnuplot plot.gp | |
integer_ver: | |
$(MAKE) -C $(KDIR) M=$(PWD) modules EXTRA_CFLAGS='-DINTEGER_OP -DOPERATION=\"INTEGER\"' | |
$(MAKE) run | |
dmesg -f kern | cut -d ' ' -f 2- >> integer.out | |
float_ver: | |
$(MAKE) -C $(KDIR) M=$(PWD) modules EXTRA_CFLAGS='-DFLOAT_OP -DOPERATION=\"FLOAT\"' | |
$(MAKE) run | |
dmesg -f kern | cut -d ' ' -f 2- >> float.out | |
run: | |
-$(MAKE) unload | |
sudo dmesg -C | |
$(MAKE) load | |
$(MAKE) unload | |
load: | |
sudo insmod floating.ko | |
unload: | |
sudo rmmod floating.ko | |
clean: | |
sudo dmesg -C | |
$(MAKE) -C $(KDIR) M=$(PWD) clean | |
$(RM) *.out compare.png | |
set terminal png | |
set output 'compare.png' | |
set xlabel 'number of iterations' | |
set ylabel 'times (ns)' | |
plot 'integer.out' using 1:2 title "Integer", \ | |
'float.out' using 1:2 title "Floating point" |