C++ 为什么Callgrind让原子负载永不停止

C++ 为什么Callgrind让原子负载永不停止,c++,profiling,valgrind,instrumentation,callgrind,C++,Profiling,Valgrind,Instrumentation,Callgrind,我编写了一个小程序,在Callgrind对其进行动态检测之前,它工作得非常好: $ g++ -std=c++11 -pthread -g -ggdb -o program.exe program.cpp $ time valgrind --tool=callgrind ./program.exe 守则: #include <atomic> #include <thread> #include <iostream> constexpr int CST_TAR

我编写了一个小程序,在Callgrind对其进行动态检测之前,它工作得非常好:

$ g++ -std=c++11 -pthread -g -ggdb -o program.exe program.cpp
$ time valgrind --tool=callgrind ./program.exe
守则:

#include <atomic>
#include <thread>
#include <iostream>

constexpr int CST_TARGET = 10*1000;

std::atomic<bool> g_lock = {false};
std::atomic<bool> g_got_work = {true};
int g_passer = 0;
long long g_total = 0;

void producer() {
    while (1) {
        while (g_lock.load(std::memory_order_seq_cst));
        if (g_passer >= CST_TARGET) {
            g_got_work.store(false, std::memory_order_seq_cst);
            return;
        }
        ++g_passer;
        g_lock.store(true, std::memory_order_seq_cst);
    }
}

void consumer() {
    while (g_got_work.load(std::memory_order_seq_cst)) {
        if (g_lock.load(std::memory_order_seq_cst)) {
            g_total += g_passer;
            g_lock.store(false, std::memory_order_seq_cst);
        }
    }
}

int main() {
    std::atomic<int> val(0);
    std::thread t1(producer);
    std::thread t2(consumer);
    t1.join();
    t2.join();
    std::cout << "g_passer = " << g_passer << std::endl;
    std::cout << "g_total = " << g_total << std::endl;
    return 0;
}
#包括
#包括
#包括
constexpr int CST_TARGET=10*1000;
原子g_锁={false};
std::原子g_got_work={true};
int g_passer=0;
长g_总计=0;
无效生产者(){
而(1){
while(g_lock.load(std::memory_order_seq_cst));
如果(g_passer>=CST_目标){
g_got_work.store(false,std::memory_order_seq_cst);
回来
}
++g_passer;
g_lock.store(true,std::memory_order_seq_cst);
}
}
无效消费者(){
while(g_got_work.load(std::memory_order_seq_cst)){
if(g_锁定加载(标准::内存顺序顺序cst)){
g_总计+=g_通行证;
g_lock.store(false,std::memory_order_seq_cst);
}
}
}
int main(){
std::原子val(0);
std::线程t1(生产者);
标准:螺纹t2(耗电元件);
t1.join();
t2.连接();

std::cout使用--fair sched=yes应该可以解决问题。

您的程序严重依赖调度抢占来工作。如果callgrind为了简化程序分析而弄乱了这一点,我不会感到惊讶。在繁忙循环中添加一个
std::this_thread::yield()
可能有助于解除阻塞。