我正在研究关于原子学的linux上的g ++ 4.4.6。我有一个简单的循环,我用来估计在原子上执行fetch_add(1)所花费的时间。
atomic<int> ia;
ia.store(0);
timespec start,stop;
clock_gettime(CLOCK_REALTIME, &start);
while (ia < THE_MAX)
{
//++ia;
ia.fetch_add(1);
}
clock_gettime(CLOCK_REALTIME, &stop);
我惊讶地发现,大约一半的时间都发生了以下情况:
volatile int ia=0;
timespec start,stop;
clock_gettime(CLOCK_REALTIME, &start);
while (ia < THE_MAX)
{
__sync_fetch_and_add( &ia, 1 );
}
clock_gettime(CLOCK_REALTIME, &stop);
我把它拆开了 - 不是说我对x86汇编程序非常好 - 而且我看到了这个主要区别。生成了C ++ 11 atomics调用
call _ZNVSt9__atomic213__atomic_baseIiE9fetch_addEiSt12memory_order
而gcc原子给出了
lock addl $1, (%eax)
我希望g ++给我最好的选择,所以我认为我对正在发生的事情有一些严重的辍学。是否有人清楚为什么C ++调用没有像gcc原子调用一样好? (也许这只是g ++ 4.4不是很成熟的问题......)。 感谢。
答案 0 :(得分:3)
这只是GCC版本和优化的问题。例如,使用gcc 4.6.3和-O3,我得到lock add
的{{1}}。
atomic<int>::fetch_add
收益率(对于带有-O3和gcc-4.6.3的x86_64):
#include <atomic>
void j(std::atomic<int>& ia)
{
ia.fetch_add(1);
}