我正在遵循并行编程模式:使用 .NET Framework 4 理解和应用并行模式第 107 页上的示例(https://www.microsoft.com/en-us/download/details.aspx?id=19222)。据称,与使用 Threadlocal.Value 本身相比,使用 ThreadLocal 的 Value 成员的本地副本速度更快。我对此进行了测试,确实如此。但为什么?
从代码中可以看出,_vector2.Value 的本地副本保存在 vector2 中,并且该本地副本用于对所有项求和。如果您使用 _vector2.Value[i] += _vector1.Value[i]
而不是 vector2[i] += vector1[i]
代码运行同样好,尽管速度较慢。这就是文章中所说的。现在 int[] 是一个引用类型。这意味着当您在 vector2 中进行复制时,您实际上是在复制 ThreadLocal 的 Value 成员中原始 int[] 的引用。通过注释证实了这一点_vector2.Value = vector2
。打印结果保持不变。所以,我认为这个任务没有必要。
现在,由于 _vector2.Value 和 vector2 引用相同的数据,为什么使用本地副本 (vector2) 仍然更快?在我的测试中大约快了 4 倍。有人知道我错过了什么吗?
class ReferenceList
{
const int VECTOR_LENGTH = 100000000;
private ThreadLocal<int[]> _vector1 = new ThreadLocal<int[]>(() => Enumerable.Range(1, VECTOR_LENGTH).ToArray());
private ThreadLocal<int[]> _vector2 = new ThreadLocal<int[]>(() => Enumerable.Range(1, VECTOR_LENGTH).ToArray());
internal void DoWork()
{
int[] vector1 = _vector1.Value;
int[] vector2 = _vector2.Value;
for (int i = 0; i < VECTOR_LENGTH; i++)
{
// This is the fast way (as in the document)
vector2[i] += vector1[i];
// This is the slow way
//_vector2.Value[i] += _vector1.Value[i];
}
// Since int[] is a reference type. This step is not needed, I think. The result is not influenced when commenting out this line
_vector2.Value = vector2;
Console.WriteLine($"Thread-{Thread.CurrentThread.ManagedThreadId} Result: {String.Join(", ", _vector2.Value.Take(10))}");
}
当年话下
相关分类