- 主题:有锁比无锁乱序快?
1. 锁不贵,撞锁才贵
2. atomic并没有规定必须无锁,事实上大部分atomic<>是有锁的,你可以用is_lock_free看一下atomic<long long>是不是无锁
3. 无锁 != 单线程,挂了atomic,甚至只是memory fence,对cache和编译器优化都是有影响的
4. 你编译用了 -o2 了没?
--
FROM 122.234.63.*
标准里唯一规定确定是无锁的是atomic_flag,其他都是impl dependent,具体是不是有锁,要用is_lock_free() 来看
【 在 libgcc 的大作中提到: 】
: 大部分atomic是有锁的?
--
FROM 122.234.63.*
测试程序本身问题更多
1. 线程没绑核独占,线程数超过核数
2. 10线程太多,瓶颈肯定在FSB带宽上
3. global variable,肯定是在L3了,各个线程又都是读+写,cache line很费,cpu内部带宽多半也有问题,baidu cache MESI protocol
4. 加锁以后编译器知道循环独占,做了cache优化,降低了撞锁,增加了cache利用
【 在 confinement 的大作中提到: 】
: 测试程序非常简单,每次就是主程序里push_back十个线程,线程执行的函数就是上面的累加函数。我测试过 -O3 编译,单纯从执行时间看,跟不带O编译看不出什么区别
: 无锁的普通 long long 类型为什么也慢。。
:
--
FROM 122.234.63.*
我的理解是:
如果不是性能敏感部分,用哪个都无所谓
性能敏感部分
容易撞锁,就用atomic,因为内部是类似spin lock,不造成context switch,但是对cache不友好,代码出现优化边界,优化效率下降。
不容易撞锁,考虑换设计吧,能单线程就尽量单线程,能共享只读就不要共享写,现在的prefetch实在太强大了。
【 在 confinement 的大作中提到: 】
另外问一下,原子变量可以以任何类型作为模板参数,那在自定义类型情形下,这东西到底有什么作用,怎么个用法?不太理解
--
FROM 122.234.63.*
hyper-thread并不能和独立的核相提并论。
hyper-thread只指如果两个指令不冲突,一个核可以同时执行这两个指令,其他所有的东西,寄存器,cache这些都是共享的。
所以你如果运行的两个指令不能同时执行,反而会造成更大的问题。
一般来说,hyper-thread会用来做一个显式的软预读,提高cache hit rate,其他并没有什么太大用处
【 在 confinement 的大作中提到: 】
: 是测试有点问题,误导了,主贴已经修改。 测试机器是8核16线程,这种,理论上是能够16线程并行运算的吧,一核2线程这种东西,对于我这样不是很懂cpu底层的,始终不是很清楚
:
--
FROM 115.193.179.*
所以现在大家意识到,其实用户层面需要只是coroutine这种可以用异步思维来编程但是实际上可以用单线程实现的东西。thread这种还是交给底层比较好,一旦multiple thread, 需要兼顾的东西太多
【 在 confinement 的大作中提到: 】
: 是测试有点问题,误导了,主贴已经修改。 测试机器是8核16线程,这种,理论上是能够16线程并行运算的吧,一核2线程这种东西,对于我这样不是很懂cpu底层的,始终不是很清楚
:
--
FROM 115.193.179.*
但凡是有shared variable的并行,都不能完全发挥核的性能。
一般来说,4核共同shared data,基本就是极限了,再往上加核,程序的瓶颈是在cache line上
【 在 ylh1969 的大作中提到: 】
: 单线程的协程,不能发挥多核的并行优势。
: 我在实验多线程协程。
: 要点是,不能使用线程锁。
--
FROM 122.224.174.*