Sinusoidal functions are very very expensive to call in C++.
Category: Uncategorized
Disable L1 and L2 CPU caches on Linux
This is inspired by me wanting to check if my code is affected (helped) heavily by CPU cache. A little bit research landed me on the following post. https://www.linuxquestions.org/questions/linux-kernel-70/disabling-cpu-caches-936077/
According to the author, disableCache.c looks like this
#include <linux/init.h> #include <linux/module.h> MODULE_LICENSE("Dual BSD/GPL"); static int disableCache_init(void) { printk(KERN_ALERT "Disabling L1 and L2 caches.\n"); __asm__(".intel_syntax noprefix\n\t" "mov eax,cr0\n\t" "or eax,(1 << 30)\n\t" "mov cr0,eax\n\t" "wbinvd\n\t" ".att_syntax noprefix\n\t" : : : "eax" ); return 0; } static void disableCache_exit(void) { printk(KERN_ALERT "Enabling L1 and L2 caches.\n"); __asm__(".intel_syntax noprefix\n\t" "mov eax,cr0\n\t" "and eax,~(1 << 30)\n\t" "mov cr0,eax\n\t" "wbinvd\n\t" ".att_syntax noprefix\n\t" : : : "eax" ); } module_init(disableCache_init); module_exit(disableCache_exit);
Makefile looks like this
EXTRA_CFLAGS = -m32 obj-m += disableCache.o all: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
Very unfortunately this code cannot be compiled on my 64 bit system. To make this compatible to my system, “EXTRA_CFLAGS = -m32” needs to be removed from the Makefile.
Also, assembly instructions need be to altered a little bit. Luckily, the cache disabling control bit on cr0 still sits on the 30th bit. The code is gonna be like this after change.
#include <linux/init.h> #include <linux/module.h> MODULE_LICENSE("Dual BSD/GPL"); static int disableCache_init(void) { printk(KERN_ALERT "Disabling L1 and L2 caches.\n"); __asm__(".intel_syntax noprefix\n\t" "mov rax,cr0\n\t" "or rax,(1 << 30)\n\t" "mov cr0,rax\n\t" "wbinvd\n\t" ".att_syntax noprefix\n\t" : : : "eax" ); return 0; } static void disableCache_exit(void) { printk(KERN_ALERT "Enabling L1 and L2 caches.\n"); __asm__(".intel_syntax noprefix\n\t" "mov rax,cr0\n\t" "and rax,~(1 << 30)\n\t" "mov cr0,rax\n\t" "wbinvd\n\t" ".att_syntax noprefix\n\t" : : : "eax" ); } module_init(disableCache_init); module_exit(disableCache_exit);
After a successful “make all” to compile, and “sudo insmod ./disableCache.ko”, the module is happily loaded into the kernel. Almost instantly you feel UNBELIEVABLE glitches on your computer which now feels like a 1980’s machine. Even the mouse cursor cannot sustain continuous move on the screen. This tells you everything is successful!
P.S. Almost forgot to mention how the cache affected my code’s performance. Sadly, not apparent. Even sadder, a few minutes later the computer became completely not operatable and I hit the restart button…
very useful command example
ls -lrt | grep "some_string" | awk {'print $9'} | xargs -I % mv % ./some_folder/
Very very unfortunate
Faltered on misunderstanding an escape sign. This is very very unfortunate.
A pit stepped into this afternoon
First let’s take a look at the following piece of code.
std::future<void> * ret_vals = new std::future<void>[3]; for (int i = 0; i < 3; ++i) { ret_val[i] = std::async([&]() {cout << "I am feeling great! Getting task " << i << endl}); }
Very trial use of async tasks and lambda in C++11 huh? I naively thought the code will produce some output like
I am feeling great! Getting task 0 I am feeling great! Getting task 1 I am feeling great! Getting task 2
But what it actually outputs is
I am feeling great! Getting task 3 I am feeling great! Getting task 3 I am feeling great! Getting task 3
It turns out that i is a variable captured by reference, and before the three async tasks have a chance to print it out, its value has long undergone many changes.