可能并发写*相同*值到整数.我需要一个原子变量吗?
possible concurrent write of *same* value to an integer. Do I need an atomic variable?
我想对一些遗留代码进行优化。优化可以归结为以下简单示例:
class Foo{
static int m_count; // allocated and initialized to -1 to indicate it's uninitialized.
void fun(){
if (m_count ==-1)
m_count = execute_db_call(); // return a val > 0.
if (m_count == 1) {
// call special == 1 optimized code.
} else {
// call expensive code.
}
}
}
-
fun()
将在数百个线程上被调用数百万次,所有这些线程都在256核服务器上并发运行。 -
execute_db_call
是昂贵的,返回值在应用程序的生命周期内是恒定的。
我需要或想要使m_count
原子吗?在最坏的情况下,多个线程可能调用execute_db_call
,并获得相同的值,然后将该值写入内存中的相同位置。即使两个线程都试图写相同的整数值,这是否是一个竞争条件?
如果我确实使成员原子化,我将为随后的只读行为带来什么样的性能开销?
Per standard§1.10/21:
如果一个程序在不同的线程中包含两个冲突的操作,且至少有一个不是原子操作,且两者都不先于另一个,则该程序的执行包含数据竞争。任何这样的数据竞争都会导致未定义的行为。
看起来你的代码符合这个定义,所以你会得到UB。现在,即使假设您的应用程序永远不会崩溃(哦,好吧……),您可能会得到不必要的execute_db_call
调用,并且您已经明确声明"execute_db_call是昂贵的",所以它仍然很糟糕。
您没有说明在进程完成后需要确保m_count
具有哪些属性(如果有的话),或者在处理过程的任何阶段它的值是否重要。在没有这些属性的情况下,还不如根本不给它赋值。如果您确实需要m_count
的值在处理过程中的任何时候都不是未定义的,那么肯定必须使用同步来确保与该变量相关的操作顺序保持一致。
如果m_count
只在-1的情况下写入,并且该变量由所有线程共享,那么将该初始化移到程序的并行部分之外会好得多。因此,您可以消除任何数据竞争,并避免不必要地调用昂贵的函数。
相关文章:
- 用C++中的一个变量定义一个常量
- 一个变量的输入值也会保存到另一个变量中
- 将双精度变量设置为另一个变量的值
- 对具有相同方法的不同类使用一个变量
- 为什么一个变量获得与另一个值相同的值
- 尝试在 C++ 中为 ifstream 提供一个变量
- 类中的一个变量显示,但另一个不显示
- 声明一个变量,该变量在 c++ 或 c 中具有值,当程序终止时不会被销毁
- c++问题:给一个变量赋值后,另一个变量发生了变化
- 如何将一个变量用于父类和派生类
- 如何在循环中使用scanf,将值存储到一个变量中,然后打印出来?
- 我如何将一个变量与另一个变量进行比较,例如我想如果(var1 > var2 x 1),然后执行此 c++
- 如何在一个函数中定义一个变量,并在另一个函数中访问和更改它?(C++)
- 如果一个变量在它之前释放了另一个(相同的数据类型)变量,如何将其分配给内存?
- 迭代器或反向器的一个变量
- fstream库,试图创建一个变量名为(c++)的文件
- 如何在 c++ 中将两个不同类型的变量分配给一个变量
- 如何将一些变量放在一个变量中?
- 将 int 转换为字符串,然后连接另一个变量以创建完整扩展名,然后将其转换为 const_char*
- 如何用索引命名一个变量来存储输入 mxArray?