现在的位置: 首页 > 综合 > 正文

linux编程的108种奇淫巧计-1(FALSE SHARING)【续】

2013年09月09日 ⁄ 综合 ⁄ 共 2453字 ⁄ 字号 评论关闭

      上篇博客:http://blog.csdn.net/pennyliang/archive/2010/10/20/5953939.aspx提出了一段代码,并没有给出解释,本文接上文继续展开讨论。

 

      该文有很多网友回复,比较集中的看法是CPU字节对齐,巧合的是有一个朋友用这个代码做了测试,发现对齐和不对齐的代码执行的速度是一样的,原因是他的笔记本安装的linux操作系统,而笔记本是单核的,所以就出现了这个状况,如果和CPU字节对齐,在单核的情况下怎么会速度一样呢?另外如果是CPU字节对齐,把线程去掉,替换成两个函数依次执行,也应该有效率的差异。 

       这是一种典型的FALSE SHARING问题,在SMP(对称多处理)的架构下常见的问题。SMP简单的说就是多个CPU核,共享一个内存和总线,L1 cache也叫芯片缓存,一般是私有的,即每个CPU核带一个,L2 cache可能是私有的也可能是部分共享的。

       为了表明FALSE SHARE带来的影响,设计了这个简单的多线程程序,包含两个线程,他们分别做求和使用不同的变量,但由于cnt_1的地址和cnt_2的地址在同一条cache line中,实测环境中cnt_1的地址为0x600c00,cnt_2的地址为0x600c08,而cache line的大小为64个字节(cache line大小可以通过getconf LEVEL1_DCACHE_LINESIZE得到,或者命令cat /sys/devices/system/cpu/cpu0/cache/index0/coherency_line_size得到),这样就会发生FALSE SHARING问题。将两个变量在64字节对齐后,cnt_1的地址为0x600c40,cnt_2的地址为0x600c80,恰好错开在两条cache line上,源代码参加上篇博客。

 

       FALSE SHARING问题在此前的博客也有详细讨论,可以参见:http://blog.csdn.net/pennyliang/archive/2010/07/27/5766541.aspx

 

       最后,可能有读者会问,有谁会这么脑残写这样的代码,日常编码怎么会碰到这样的问题呢?我给大家说一个具体的场景,假如有一个lock-free的queues,里面包含了很多类型的queue,每个queue包含一个head和一个tail,这两个值分别被消费者和生产者之间竞争,因此如果不考虑false sharing问题,可能会造成低效代码。这样一个多线程共享的队列结构(多生产者,多消费者共享)用以下哪种结构更好呢?我不再公布答案,有兴趣的朋友可以去找找这方面的代码,看看他们是怎么写的。

      【1】

       struct queues{

                  type head1 

                  type head2

                  ...

                  type headn

                  type tail1

                  type tail2

                  ...

                  type tailn 

       }

      【2】

       struct queue{

                  type head1 

                  type tail1

                  type head2

                  type tail2

                  ...

                  type headn

                  type tailn 

       }

       【3】

        struct queue{

                  type head1 

                  type head2

                  ...

                  type headn

                  type add_enough_padding;

                  type tail1

                  type tail2

                  ...

                  type tailn

                  type add_enough_padding; 

       }

       【4】

        struct queue{

                  type head1

                  type add_enough_padding; 

                  type tail1

                  type add_enough_padding; 

                  type head2

                  type add_enough_padding; 

                  type tail2

                  type add_enough_padding; 

                  ...

                  type headn

                  type add_enough_padding; 

                  type tailn

                  type add_enough_padding;  

       }

          

在上次的博客linux编程的108种奇淫巧计-1(FALSE SHARING)我们给出了代码,但并没有解释,本文给出一些详细解释。

抱歉!评论已关闭.