執行 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" |