std::atomic<T>
与无争议的原子变量(例如C++)操作相比,它快/慢多少。
另外,有争议的原子变量相对于无争议的锁要慢多少?
我正在研究的架构是 x86-64。
std::atomic<T>
与无争议的原子变量(例如C++)操作相比,它快/慢多少。
另外,有争议的原子变量相对于无争议的锁要慢多少?
我正在研究的架构是 x86-64。
我碰巧有很多低级速度测试。但是,速度的确切含义是非常不确定的,因为它在很大程度上取决于您到底在做什么(甚至与操作本身无关)。
以下是 AMD 64 位 Phenom II X6 3.2Ghz 的一些数字。我也在英特尔芯片上运行过它,而且时间确实有很大差异(同样,取决于正在做的事情)。
一个 GCC __sync_fetch_and_add
,这将是一个完全隔离的原子加法,平均为 16ns,最短时间为 4ns。最短时间可能更接近事实(尽管即使在那里我也有一些开销)。
一个无争议的 pthread 互斥体(通过 boost)是 14ns(这也是它的最小值)。请注意,这也有点太低了,因为如果其他东西锁定了互斥体,但它现在不是没有争议的(因为它会导致缓存同步),时间实际上会增加。
失败的 try_lock 为 9ns。
我没有一个普通的旧原子公司,因为在 x86_64 上这只是一个正常的交换操作。可能接近最小可能时间,所以 1-2ns。
在条件变量上调用没有服务员的通知是 25ns(如果有东西在等待大约 304ns)。
然而,由于所有锁都会导致某些 CPU 排序保证,因此您已修改的内存量(无论适合存储缓冲区的内存量)将改变此类操作所需的时间。很明显,如果您曾经对互斥锁发生争用,那是您最糟糕的时刻。即使实际上没有发生线程切换,任何返回到 linux 内核的时间都可能是数百纳秒。这通常是原子锁表现不佳的地方,因为它们不涉及任何内核调用:平均情况下的性能也是最差的情况。如果有等待线程,互斥锁解锁也会产生开销,而原子则不会。
注意:做这样的测量充满了问题,所以结果总是有问题的。我的测试试图通过固定 CPU 速度、设置线程的 cpu 亲和性、不运行其他进程以及对大型结果集进行平均来最小化变化。
GitHub 上有一个项目,目的是在不同平台上进行测量。不幸的是,在我的硕士论文之后,我从来没有真正有时间跟进这个,但至少基本代码在那里。
__sync_fetch_and_add
与内在相比,它测量 pthread 和 OpenMP 锁。
据我所知,我们预计锁和原子操作之间会有相当大的差异(〜一个数量级),但实际差异却非常小。
然而,现在在我的系统上测量得到的结果反映了我最初的猜测,即(无论使用 pthread 还是 OpenMP)原子操作的速度大约快五倍,单个锁定增量操作大约需要 35ns(这包括获取锁) ,执行增量,并释放锁)。