gpt4 book ai didi

C# volatile 读取行为

转载 作者:行者123 更新时间:2023-11-30 12:23:21 26 4
gpt4 key购买 nike

在 C#.net ConcurrentDictionary ( C# reference source ) 的引用源代码中,我不明白为什么在以下代码片段中需要 volatile 读取:

public bool TryGetValue(TKey key, out TValue value)
{
if (key == null) throw new ArgumentNullException("key");
int bucketNo, lockNoUnused;

// We must capture the m_buckets field in a local variable.
It is set to a new table on each table resize.
Tables tables = m_tables;
IEqualityComparer<TKey> comparer = tables.m_comparer;
GetBucketAndLockNo(comparer.GetHashCode(key),
out bucketNo,
out lockNoUnused,
tables.m_buckets.Length,
tables.m_locks.Length);

// We can get away w/out a lock here.
// The Volatile.Read ensures that the load of the fields of 'n'
//doesn't move before the load from buckets[i].
Node n = Volatile.Read<Node>(ref tables.m_buckets[bucketNo]);

while (n != null)
{
if (comparer.Equals(n.m_key, key))
{
value = n.m_value;
return true;
}
n = n.m_next;
}

value = default(TValue);
return false;
}

评论:

// We can get away w/out a lock here.
// The Volatile.Read ensures that the load of the fields of 'n'
//doesn't move before the load from buckets[i].
Node n = Volatile.Read<Node>(ref tables.m_buckets[bucketNo]);

让我有点困惑。

在从数组中读取变量 n 本身之前,CPU 如何读取 n 的字段?

最佳答案

volatile 读取具有获取语义,这意味着它先于其他内存访问。

如果不是 volatile 读取,下一次从 Node 读取的字段可能会被 JIT 编译器或架构重新排序,推测性地,在读取之前到节点本身。

如果这没有意义,请想象一个 JIT 编译器或架构读取将分配给 n 的任何值,并开始 speculatively read n.m_key,如果 n != null,则没有 mispredicted branch , 没有 pipeline bubble或者更糟,pipeline flushing .

这是可能的 when the result of an instruction can be used as an operand for the next instruction(s) ,同时还在筹备中。

对于 volatile 读取或具有类似获取语义的操作(例如进入锁),C# 规范和 CLI 规范均规定它必须在任何进一步的内存访问之前发生,因此不可能获得未初始化的 n.m_key.

也就是说,如果写入也是 volatile 的或由具有类似释放语义的操作(例如退出锁)保护。

如果没有可变语义,这样的推测性读取可能会为 n.m_key 返回一个未初始化的值。

同样重要的是由比较器执行的内存访问。如果节点的对象是在没有 volatile 释放的情况下初始化的,您可能正在读取陈旧的、可能未初始化的数据。

Volatile.Read 在这里是必需的,因为 C# 本身无法表达对数组元素的 volatile 读取。读取 m_next 字段时不需要它,因为它被声明为 volatile

关于C# volatile 读取行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37275421/

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