C++ 在源文件中定义静态原子变量不正确?

C++ 在源文件中定义静态原子变量不正确?,c++,multithreading,performance,static,atomic,C++,Multithreading,Performance,Static,Atomic,如果我们在源文件(.cpp)中定义静态全局变量 //在cpp中定义的变量 静态标准::原子fps=-1.0; 静态std::atomicisSysUp=FALSE//WinAPI布尔 静态std::原子isMessaginDone=false; void foo() { while(isSysUp&&isMessaginDone)//具有seq.一致的内存顺序 { //……一些代码// 睡眠(1ms); } } 空条() { 如果(isSysUp) { 如果(/…条件…/) { isMessag

如果我们在源文件(.cpp)中定义静态全局变量

//在cpp中定义的变量
静态标准::原子fps=-1.0;
静态std::atomicisSysUp=FALSE//WinAPI布尔
静态std::原子isMessaginDone=false;
void foo()
{
while(isSysUp&&isMessaginDone)//具有seq.一致的内存顺序
{
//……一些代码//
睡眠(1ms);
}
}
空条()
{
如果(isSysUp)
{
如果(/…条件…/)
{
isMessaginDone=false;
}    
}
}
void termi()
{
isSysUp=false;
}
这里foo使用主线程调用,而使用子线程调用其他函数

Say函数foo每隔10ms调用一次,就像游戏循环一样。 使用带有静态内部链接的std::atomic,并在内存顺序中执行加载存储操作是否会降低性能?而且不安全

在上述情况下使用std::store(std::memory\u order\u release)std::load(std::memory\u order\u acquire)以获得线程安全性能是否明智


(因为在函数foo中,只读取原子布尔值,而不是像在函数bartermi中那样写入一次)

在编译单元中使用静态原子与在编译单元中使用静态全局变量一样糟糕或必要

性能问题可能由瓶颈引起。但这更多地与线程和一致性需求之间共享变量的使用有关,而不是微妙的内存排序问题

尽管这取决于实现,但基于简单基本类型(如bool或int)的原子通常是在支持原子CPU指令的情况下实现的,因此可能根本没有性能问题

例如,根据您的定义:

   while (!isMessaginDone) 
将被翻译成

   movzx eax, BYTE PTR isMessaginDone[rip]  ; already atomic CPU instruction
   test al, al
和一个像

   isMessaginDone=true; 
将成为

   mov BYTE PTR isMessaginDone[rip], 1
   mfence           ;  compiler is taking care of the memory ordering
另一方面,实现可以自由使用基于锁的原子实现(例如,使用信号量等),这将需要一个代价高昂的操作系统调用。但在这种情况下,内存排序的欺骗不会改变CPU调用的成本,也不会带来预期的性能提升


因此,不要在过早优化的尝试中迷失方向。使用原子,查看asm,如果需要,执行基准测试

是的,它会降低性能。我想你应该锁定互斥锁,在你的代码中,我可以看到自旋锁,试着摆脱它。@RohiniSingh,它会降低性能吗?旋转锁!但是使用加载和存储在内存中是否不好?是的,性能会很慢,因为它必须与所有线程同步。我建议如果您真的需要它,请转到其他位置。谢谢您的回答,非常有用。为什么在这里使用静态对翻译单元不好,而不是将其声明为非静态全局?@Buddhika static global是绝对优于非静态全局。我认为,有时有必要甚至有理由建立这样一个全球机制。但我没有资格对你的具体案件做出判断。有时使用全局变量是为了方便,而不是为了更好地设计类交互。这就是为什么我将好的/坏的问题留待讨论,并将重点放在原子上。如果您不介意的话,除了std::atomic之外,您能告诉我在这种情况下,从性能和安全角度来看,哪种方法最适合?使用联锁/信号灯?或者使用互斥锁/关键部分?还是其他技术?我知道与其他方法相比,使用互斥/关键部分会带来性能损失。。更好的诀窍是什么?:)就我个人而言,我喜欢原子学。然而,设计无锁算法可能比假设的要困难得多。因此,互斥锁通常用于保护关键部分。如果您想了解更多,我强烈推荐Anthony Williams(他经常这样做)的“c++并发操作”。这是一本关于并发、线程和原子和C++的伟大著作。@ Buddhika。如果你想深入原子论,这里有一个很好的会议,从赫伯萨特免费提供:
   mov BYTE PTR isMessaginDone[rip], 1
   mfence           ;  compiler is taking care of the memory ordering