Implementation of Long Atomic Int
Implementation of Long Atomic Int
我想使用计数通常为2^40的原子计数器(多线程计算),因此我不能直接使用32位int原子计数器。我还没有c++11(我会迁移到它,但还没有,因为这对我来说是有成本的),我必须在32位和64位平台上编译。我目前使用QT,所以我可以使用QAtomicInt。
我是这么想的:
(initialization...)
QAtomicInt counterLo = 0;
QAtomicInt counterHi = 0;
void increment()
{
int before = counterLo.fetchAndAddOrdered(1);
if(before==INT_MAX)
{
counterHi.fetchAndAddOrdered(1); //Increment high word
counterLo.fetchAndAddOrdered(INT_MAX); //Increments low word to -1
counterLo.fetchAndAddOrdered(1); //Increments low word to 0
}
}
uint64_t value()
{
//Wait until the low word is non-negative
int lo = counterLow;
while(lo<0)
lo = counterLow;
return (uint64_t)counterHi * ((uint64_t)INT_MAX+1) + (uint64_t)lo;
}
正确吗?我已经尝试用互斥锁来制作计数器,但是我损失了大约10%的性能。每秒大约被调用100万次,在8个线程之间共享(蒙特卡罗模拟的示例计数器)
谢谢!
这不是完全原子化的,参见下面的例子:
-
hi=0,lo=INT_MAX
- T1呼叫
value()
,接lo=INT_MAX
,中断 - T2调用
increment()
将hi递增到1 - T1恢复并读取
counterHi
,获得1,返回值2^32 + INT_MAX
这可能不是您想要的。难道不能分割样本空间,让每个线程计算n/8个项目而不争用锁吗?
当然这不是原子的。原子操作序列可能被中断。我建议使用保护(互斥锁或临界区)
相关文章:
- 为什么在全局范围内使用"extern int a"似乎不行?
- int(c) 和 c-'0' 之间的区别。C++
- 从"int*"强制转换为"unsigned int"会丢失精度错误
- 为什么野牛仍在使用"int yylex(void)",却找不到"int yylex(YYS
- 如何从 std::atomic 中提取指针 T<T>?
- 有符号的int和int-有没有一种方法可以在C++中区分它们
- 请解释这句话(cout<<1+int((a<b)^((b-a)&1) )<<endl
- 是否可以从int转换为enum类类型
- 不能在初始值设定项列表中将非常量表达式从类型 'int' 缩小到'unsigned long long'
- 向量 <int> a {N, 0} 和 int arr a[N] = {0} 的时间复杂度有什么区别
- 'short int'持有的值溢出,但"自动"不会溢出?
- 为什么我的 std::atomic<int> 变量不是线程安全的?
- 按值对 std::unordered_map<std:::string, std::atomic<unsigned int>> 进行排序
- std::atomic<int> - 原子加载并重置为 0?
- std::atomic<int*>::load 应该做一个比较和交换循环吗?
- 在Windows中等待std::atomic的正确方法<int>?
- 较低级别的 std::atomic<unsigned int>
- 我可以制作一个线程安全的 std::atomic<vector<int>>吗?
- Implementation of Long Atomic Int
- 如何打印 std::atomic<unsigned int> 的值?