首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >原子操作比锁定时间更长(没有争用)

原子操作比锁定时间更长(没有争用)
EN

Stack Overflow用户
提问于 2019-06-12 05:46:02
回答 1查看 134关注 0票数 2

当没有争用时,我试图度量各种同步选项的开销。我使用以下程序:

代码语言:javascript
复制
#include <atomic>
#include <chrono>
#include <iostream>
#include <mutex>

void function() {
    static volatile uint64_t counter = 0;
    counter++;
}

void function2() {
    std::atomic<uint64_t> counter2 = 0;
    counter2++;
}

int main() {
    // warm up the cache
    std::mutex lock;
    for( int i=0; i<1'000'000; ++i ) {
        std::lock_guard<std::mutex> locker(lock);
        function();
        function2();
    }

    std::cout<<"Starting test\n";
    auto start = std::chrono::high_resolution_clock::now();
    for( int i=0; i<1'000'000; ++i ) {
        std::lock_guard<std::mutex> locker(lock);
        function();
    }
    auto end = std::chrono::high_resolution_clock::now();
    std::cout<<"  With lock took "<<std::chrono::ceil<std::chrono::nanoseconds>(end-start).count()<<"ns\n";

    start = std::chrono::high_resolution_clock::now();
    for( int i=0; i<1'000'000; ++i ) {
        function();
    }
    end = std::chrono::high_resolution_clock::now();
    std::cout<<"    No lock took "<<std::chrono::ceil<std::chrono::nanoseconds>(end-start).count()<<"ns\n";

    start = std::chrono::high_resolution_clock::now();
    for( int i=0; i<1'000'000; ++i ) {
        function2();
    }
    end = std::chrono::high_resolution_clock::now();
    std::cout<<"Atomic lock took "<<std::chrono::ceil<std::chrono::nanoseconds>(end-start).count()<<"ns\n";
}

用gcc或clang编写,我得到了类似的结果:

代码语言:javascript
复制
$ clang++-7 -g -O3 -std=c++2a locking.cpp -o locking && ./locking 
Starting test
  With lock took 2099204ns
    No lock took 2126724ns
Atomic lock took 12922543ns

因此,不管是否锁定,结果都是相似的(通常没有锁定会稍微快一些),但是对于原子操作,我的x6性能会受到影响。

逻辑上说,在没有争用的情况下,相关变量都是运行中的CPU缓存的本地变量,而所有同步选项都将产生或多或少的相同性能。

我遗漏了什么?

EN

回答 1

Stack Overflow用户

发布于 2019-06-12 06:40:52

问题在于基准测试程序。

第一种情况是,std::atomic没有被声明为static,导致在每次迭代时使用一个新的。第二个问题是程序不是用-pthread编译的,导致锁定代码变成无操作(这解释了为什么具有锁定的代码以与不带锁的代码相同的速度运行)。

解决这两个问题的结果是:

代码语言:javascript
复制
Starting test
  With lock took 21013047ns
    No lock took 2125868ns
Atomic lock took 6744567ns

所以原子方法比没有锁定慢3倍,而实际锁定大约慢10倍。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56555372

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档