False sharing问题及其解决方法
October 21st, 2010
11 comments
原创文章,转载请注明: 转载自系统技术非业余研究
本文链接地址: False sharing问题及其解决方法
在做多线程程序的时候,为了避免使用锁,我们通常会采用这样的数据结构:根据线程的数目,安排一个数组, 每个线程一个项,互相不冲突. 从逻辑上看这样的设计无懈可击,但是实践的过程我们会发现这样并没有提高速度. 问题在于cpu的cache line. 我们在读主存的时候,数据同时被读到L1,L2中去,而且在L1中是以cache line(通常64)字节为单位的. 每个Core都有自己的L1,L2,所以每个线程在读取自己的项的时候, 也把别人的项读进去, 所以在更新的时候,为了保持数据的一致性, core之间cache要进行同步, 这个会导致严重的性能问题. 这就是所谓的False sharing问题, 有兴趣的同学可以wiki下.
具体的参考文章: http://software.intel.com/en-us/articles/avoiding-and-identifying-false-sharing-among-threads/
解决方法很简单:
把每个项凑齐cache line的长度,实现隔离.
typedef union { erts_smp_rwmtx_t rwmtx; byte cache_line_align__[ERTS_ALC_CACHE_LINE_ALIGN_SIZE( sizeof(erts_smp_rwmtx_t))]; } erts_meta_main_tab_lock_t; 或者 _declspec (align(64)) int thread1_global_variable; __declspec (align(64)) int thread2_global_variable;
这就是为什么在高性能服务器中到处看到cache_line_align, 号称是避免cache的trash.
类似valgrind和intel vtune的工具可以做这个层次的性能微调.
Post Footer automatically generated by wp-posturl plugin for wordpress.
Recent Comments