gpt4 book ai didi

c++ - 非阻塞 pthread 停止 - 或者为什么 std::atomic_flag 会减慢我的代码

转载 作者:行者123 更新时间:2023-11-30 05:18:08 30 4
gpt4 key购买 nike

我实现了一个小的多线程应用程序,它执行以下操作:

主线程

A main thread starts a timer using setitimer and starts up to 8 threads. The timer from the main thread is used to read repeatedly from > a file (every 0.25s). When the timer is called 20 times (after ~5s), I want to stop the threads and get the amount of computations done by every thread.

主线程.h

class MainThread {
private:
int counter;
ThreadManager tm;
bool registerTimer(double seconds);
void startTimerWithInterval(double interval);
void read() {
/**
* If counter >= 20, call stopWorker on all threads
*/
tm.stopWorkers();
}
public:
MainThread():counter(0){}
}

WorkerThreads

Perform some expensive computations whithin an infinity loop. After a certain amount of computations, the thread has to store the number of computations it performed. This value (amount of computations) has to be quite accurate, so i think I have to stop the threads (quite) immediatly.

线程类.h

class WorkerThread { 
private:
/**
* ...
*/
std::atomic_flag keep_Running = ATOMIC_FLAG_INIT;

static void* run(void* args) {
((WorkerThread*)args)->process();
pthread_exit(nullptr);
return nullptr;
}

public:
/**
* ...
*/
bool startWorker() {
keep_Running.test_and_set();
bool result = (pthread_create(&thread, pthread_attr, run, this) == 0);
if(!result) {
keep_Running.clear();
}
return result;
}
void stopWorker() {
keep_Running.clear();
}
bool keepRunning() {
return keep_Running.test_and_set();
}
virtual void process() = 0;
};

计算线程.h

class ComputationThread : public WorkerThread {
public:
virtual void process() override {
/**
* Perform computations with ~400MB data
* check every 16B, whether keepRunning still true
*/
bool keep_running = true;
while(keep_running) {
/**
* Process 4B
*/
keep_running = keepRunning();
}
}
};

如果我使用某种标志来跟踪线程的运行状态,我必须使该标志成为线程安全的,不是吗?我尝试了 std::atomic_flag,因为它应该是无锁的并且具有原子操作,但这会导致性能急剧下降。我的问题是,std::atomic_flag 是否会导致性能下降,或者这仅仅是因为我过于频繁地执行检查?有谁知道更好的方法吗?

在你问之前,我必须使用 pthread 而不是 std::thread 将线程分配给线程创建中的指定核心(使用 pthread_attrib_t )。

最佳答案

不要使用 std::atomic_flag .

它意味着低级别 atomic原始的,因此接口(interface)非常有限。
它的主要限制是您只能通过在单个 atomic 中将它设置为 true 来测试它的值。调用名为 test_and_set()
这是一个读取-修改-写入操作 (RMW),它在所有内核之间执行昂贵的同步。由于您在每次循环迭代中都调用它,因此它会显着减慢速度。

使用常规 atomic<bool>完成后进行设置。这样,在循环内你只需要读取它,这是一个 atomic加载并转换为常规 mov手术。设置特定的内存顺序不会影响性能(至少在 X86 上)。

关于c++ - 非阻塞 pthread 停止 - 或者为什么 std::atomic_flag 会减慢我的代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41882223/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com