Почему Callgrind делает атомную нагрузку бесконечной - PullRequest
0 голосов
/ 21 мая 2019

Я написал небольшую программу, которая прекрасно работает, пока она не будет динамически оснащена 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;
}

Инструментарий не закончится через 10 минут, поэтому я прекратил его и посмотрел статистику KCachegrind.Есть сотни миллионов или миллиарды звонков на std::atomic<bool>::load(...).

Есть идеи, какие части Callgrind изменили поведение атомарных вызовов и потерпели неудачу?Сама программа работает за миллисекунды без Callgrind.

1 Ответ

1 голос
/ 22 мая 2019

Использование --fair-sched = yes должно решить проблему.

...