您的位置:首页 > 运维架构 > Linux

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

2010-10-26 12:40 309 查看
上篇博客: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)我们给出了代码,但并没有解释,本文给出一些详细解释。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: