gpt4 book ai didi

c++ - 没有 std::atomics 的无锁哈希保证在 C++11 中是线程安全的吗?

转载 作者:太空狗 更新时间:2023-10-29 23:41:14 25 4
gpt4 key购买 nike

考虑以下针对多线程搜索算法的无锁哈希表的尝试(受此启发paper)

struct Data
{
uint64_t key;
uint64_t value;
};

struct HashEntry
{
uint64_t key_xor_value;
uint64_t value;
};

void insert_data(Data const& e, HashEntry* h, std::size_t tableOffset)
{
h[tableOffset].key_xor_value = e.key ^ e.value;
h[tableOffset].value = e.value;
}

bool data_is_present(Data const& e, HashEntry const* h, std::size_t tableOffset)
{
auto const tmp_key_xor_value = h[tableOFfset].key_xor_value;
auto const tmp_value = h[tableOffset].value;

return e.key == (tmp_key_xor_value ^ tmp_value);
}

想法是 HashEntry struct 存储 Data 的两个 64 位字的异或组合结构。如果两个线程对 HashEntry 的两个 64 位字进行交错读/写struct,这个想法是,这可以通过再次异或运算并与原始 key 进行比较,由读取线程检测到.因此,损坏的哈希条目可能会降低效率,但在解码检索到的 key 与原始 key 匹配的情况下,仍然可以保证正确性。

论文提到它基于以下假设:

For the remainder of this discussion, assume that 64 bit memory read/write operations are atomic, that is the entire 64 bit value is read/written in one cycle.

我的问题是:上面的代码没有明确使用std::atomic<uint64_t>吗?保证在 C++11 中是线程安全的?或者单个 64 位字是否会因同时读/写而损坏?即使在 64 位平台上?这与旧的 C++98 标准有何不同?

从标准中引用将不胜感激。

更新:基于 Hans Boehm on "benign" data races 的这篇精彩论文, 一个简单的被咬住的方法是让编译器取消来自 insert_data() 的两个异或运算。和 data_is_present()总是返回true ,例如如果它找到像

这样的本地代码片段
insert_data(e, h, t);
if (data_is_present(e, h, t)) // optimized to true as if in single-threaded code
read_and_process(e, h, t); // data race if other thread has written

最佳答案

C++11 规范几乎将一个线程读取或写入另一个线程正在写入的内存位置的任何尝试定义为未定义行为(不使用原子或互斥锁来防止同时从一个线程读取/写入另一个线程正在写入)。

个别编译器可能使其安全,但 C++11 规范本身并未提供覆盖范围。同时读取从来都不是问题;它在一个线程中写入,而在另一个线程中读取/写入。

And how is this different from the old C++98 Standard?

C++98/03 标准不提供关于线程的任何覆盖范围。就 C++98/03 内存模型而言,threading is not a thing that can possibly happen .

关于c++ - 没有 std::atomics 的无锁哈希保证在 C++11 中是线程安全的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12507705/

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