我非常好奇于不同同步原理的性能,于是对atomic, spinlock和mutex做了如下实验来比较:
1 #include <future> 2 #include <iostream> 3 4 volatile int value = 0; 5 6 int loop (bool inc, int limit) { 7 std::cout << "Started " << inc << " " << limit << std::endl; 8 for (int i = 0; i < limit; ++i) { 9 if (inc) { 10 ++value; 11 } else { 12 --value; 13 } 14 } 15 return 0; 16 } 17 18 int main () { 19 auto f = std::async (std::launch::async, std::bind(loop, true, 20000000));//开启一个线程来执行loop函数,c++11的高级特性 20 loop (false, 10000000); 21 f.wait (); 22 std::cout << value << std::endl; 23 }
通过clang编译器:
1 clang++ -std=c++11 -stdlib=libc++ -O3 -o test test.cpp && time ./test
运行:
1 SSttaarrtteedd 10 2100000000000000 2 3 11177087 4 5 real 0m0.070s 6 user 0m0.089s 7 sys 0m0.002s
从运行结果很显然的我们可以看出增减不是原子性操作的,变量value最后所包含的值是不确定的(垃圾)。
2. 汇编LOCK
1 #include <future> 2 #include <iostream> 3 4 volatile int value = 0; 5 6 int loop (bool inc, int limit) { 7 std::cout << "Started " << inc << " " << limit << std::endl; 8 for (int i = 0; i < limit; ++i) { 9 if (inc) { 10 asm("LOCK"); 11 ++value; 12 } else { 13 asm("LOCK"); 14 --value; 15 } 16 } 17 return 0; 18 } 19 20 int main () { 21 auto f = std::async (std::launch::async, std::bind(loop, true, 20000000)); //开启一个线程来执行loop函数,c++11的高级特性 22 loop (false, 10000000); 23 f.wait (); 24 std::cout << value << std::endl; 25 }