- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在尝试测量没有争用时各种同步选项的开销。我使用以下程序:
#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 编译,我得到类似的结果:
$ 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 缓存的本地,并且所有同步选项都会或多或少地产生相同的性能。
我错过了什么?
最佳答案
问题出在基准程序上。
首先是 std::atomic
没有被声明为 static
,导致每次迭代都使用一个新的。第二个问题是程序没有用-pthread
编译,导致加锁的代码变成了no-op(这也解释了为什么带锁的代码运行速度和不加锁的一样)。
解决这两个问题会产生:
Starting test
With lock took 21013047ns
No lock took 2125868ns
Atomic lock took 6744567ns
所以原子方法比没有锁定慢大约 3 倍,而实际锁定大约慢 10 倍。
关于c++ - 原子操作比锁定花费的时间更长(无争用),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56555372/
我一直在读一本分配给类(class)的书,它提到数组访问需要 O(1) 时间。我意识到这非常快(也许尽可能快),但是如果您有一个循环必须多次引用它,那么分配一个临时变量以在数组中查找值有什么好处吗?或
我一直试图找出为什么这个查询花了这么长时间。以前,它的执行时间约为 150 毫秒到 200 毫秒,但现在需要 25 秒或更长时间。这是从昨晚到今天之间的事。唯一改变的就是将数据添加到表中。 根据下面的
我有一个 ng repeat 重复数据。 - data.image(src)部分为null,src=null的不再重复。 我用一个简单的 ng-if 解决了它。
我有一个包含大量测试的 Laravel 项目。我正在使用 pcov 来计算代码覆盖率,大约需要 4 分钟。但是 pcov 不支持分支覆盖,所以我决定使用 xdebug。 使用 xdebug 测试执行,
我已经被这个问题困扰了一段时间了,我被难住了。 Automapper 需要 4 秒来映射 19 个对象。在我的机器(24GB 内存,3.6Ghz i7)上,该操作应该花费毫秒或纳秒。 这是映射调用。
我有一个包含大量测试的 Laravel 项目。我正在使用 pcov 来计算代码覆盖率,大约需要 4 分钟。但是 pcov 不支持分支覆盖,所以我决定使用 xdebug。 使用 xdebug 测试执行,
我在机器 A 上有一个 java 进程通过 TCP 与机器 B 上的 Tomcat 通信。 TCP 连接(只是 syn-syn/ack 交换)始终需要 100 毫秒的数量级,而 ping 请求需要 1
我做了一项任务,从 sqlserver 获取超过 200 万条记录并将它们填充到 Asp.net GridView 中。 问题是,查询需要超过 2 分钟才能获得记录,而我的查询现在已经完全优化。 当我
我希望将 165 秒变成 2:40 而不是 0:2:45 函数需要能够适应秒值的大小。 我知道有无数种方法可以做到这一点,但我正在寻找一种干净的方法来做到这一点,除了 jQuery 之外没有任何外部库
我是一名优秀的程序员,十分优秀!