【发布时间】:2022-01-08 17:30:18
【问题描述】:
我试图用 c++ 编写一个队列,我从 intel dpdk libring 中了解到,我可以通过使用 unsigned wrap around 属性编写类似的代码来做到这一点:
#include <cstdio>
#include <cassert>
#include <atomic>
#include <thread>
size_t global_r = 0, global_w = 0, mask_ = 3;
void emplace() {
unsigned long local_w, local_r, free_entries = 0;
local_w = global_w;
while (free_entries == 0) {
local_r = global_r;
free_entries = (mask_ + local_r - local_w);
}
fprintf(stderr, "%lu\n", free_entries);
auto w_next = local_w + 1;
std::atomic_thread_fence(std::memory_order_release);
global_w = w_next;
}
void pop() {
unsigned long local_r = global_r;
unsigned long r_next = local_r + 1;
// make sure nobody can write to it before destruction
std::atomic_thread_fence(std::memory_order_release);
global_r = r_next;
}
int main() {
std::jthread([]() -> void {
int i = 10;
while (i-- >= 0) emplace();
});
std::jthread([]() -> void {
int i = 10;
while (i-- >= 0) pop();
});
return 0;
}
当我使用 g++ O0 和 O2 运行它时,它会产生不同的结果: 与 O2:
3
2
1
0
18446744073709551615
18446744073709551614
18446744073709551613
18446744073709551612
18446744073709551611
18446744073709551610
18446744073709551609
没有氧气:
3
2
1
.....long time suspending
我想知道我对 unsinged wrap around 的理解有什么问题吗? (我从几个 stackoverflow 帖子和其他参考资料中了解到,未分割的环绕是已定义的行为)。
【问题讨论】:
标签: c++ g++ unsigned-integer