当使用pthread时,使用全局variables的C ++显示比指针慢100%?

我有一个相当程序来显示2个类似的程序的性能,都使用2个线程来做计算。 核心的区别是一个使用全局variables,另一个使用“新”对象,如下所示:

#include<pthread.h> #include<stdlib.h> struct M{ long a; long b; }obj; size_t count=2000000000; void* addx(void*args){ long*pl=(long*)args; for(size_t i=0;i<count;++i) (*pl)*=i; return NULL; } int main(int argc,char*argv[]){ pthread_t tid[2]; pthread_create(&tid[0],NULL,addx,&obj.a); pthread_create(&tid[1],NULL,addx,&obj.b); pthread_join(tid[0],NULL); pthread_join(tid[1],NULL); return 0; } clang++ test03_threads.cpp -o test03_threads -lpthread -O2 && time ./test03_threads real 0m3.626s user 0m6.595s sys 0m0.009s 

这是很慢,然后我修改obj被dynamic创build(我预计它会更慢):

 #include<pthread.h> #include<stdlib.h> struct M{ long a; long b; }*obj;//difference 1 size_t count=2000000000; void* addx(void*args){ long*pl=(long*)args; for(size_t i=0;i<count;++i) (*pl)*=i; return NULL; } int main(int argc,char*argv[]){ obj=new M;//difference 2 pthread_t tid[2]; pthread_create(&tid[0],NULL,addx,&obj->a);//difference 3 pthread_create(&tid[1],NULL,addx,&obj->b);//difference 4 pthread_join(tid[0],NULL); pthread_join(tid[1],NULL); delete obj;//difference 5 return 0; } clang++ test03_threads_new.cpp -o test03_threads_new -lpthread -O2 && time ./test03_threads_new real 0m1.880s user 0m3.745s sys 0m0.007s 

这比以前快了100%。 我也在linux上试过g ++,结果相同。 但是如何解释呢? 我知道obj是全局variables,但* obj仍然是全局variables,只是dynamic创build。 核心区别是什么?

我认为这确实是因为不重要的建议而被虚假的分享。

为什么不同呢,你可能会问?

由于count变量! 由于这是一个变量 ,并且size_t的底层类型恰好适合您,所以编译器无法优化它(因为pl可能指向count )。 如果count是一个int ,由于严格的别名规则,编译器可以优化它(或者简单地说它可以是const size_t )。

所以生成的代码必须在循环中每次读取。

在第一个例子中, countobj都是全局变量,它们相互靠近放置。 所以,链接器很有可能把这些变量放到同一个缓存行中。 所以写入obj.aobj.b会使count的缓存行无效。 所以CPU必须同步读取count

在第二个例子中, obj被分配在堆上,它的地址将会远离count ,所以它们不会占用相同的缓存行。 count不需要同步