adv*_*v12 6 c# multithreading memory-barriers parallel.for
Microsoft的Parallel.For文档包含以下方法:
static void MultiplyMatricesParallel(double[,] matA, double[,] matB, double[,] result)
{
int matACols = matA.GetLength(1);
int matBCols = matB.GetLength(1);
int matARows = matA.GetLength(0);
// A basic matrix multiplication.
// Parallelize the outer loop to partition the source array by rows.
Parallel.For(0, matARows, i =>
{
for (int j = 0; j < matBCols; j++)
{
double temp = 0;
for (int k = 0; k < matACols; k++)
{
temp += matA[i, k] * matB[k, j];
}
result[i, j] = temp;
}
}); // Parallel.For
}
Run Code Online (Sandbox Code Playgroud)
在此方法中,可能有多个线程从调用线程读取matA
和matB
创建并初始化的值,并且可能有多个线程将值写入result
,稍后由调用线程读取.在传递给lambda的范围内Parallel.For
,数组的读写没有明确的锁定.因为这个例子来自微软,我认为它是线程安全的,但我试图了解幕后发生的事情,使其成为线程安全的.
根据我所阅读的内容以及我在SO上提出的其他问题(例如本文),我需要考虑几个内存障碍才能使这一切顺利进行.那些是:
matA
和matB
,matA
和matB
,result
,和result
.我理解正确吗?
如果是这样,那么Parallel.For
以某种方式做到了吗?我去了参考源,但是在编写代码时遇到了麻烦.我没有看到任何lock
阻止或MemoryBarrier
通话.
由于数组已经创建,因此写入或读取数组不会导致任何调整大小.此外,代码本身也阻止在数组中读/写相同的位置.
底线是代码总是可以计算在数组中读取和写入的位置,并且这些调用永远不会相互交叉.因此,它是线程安全的.
在线程(实际上是:任务)内部对 matA 和 matB 的访问是只读的,结果是只写的。
并行读取本质上是线程安全的,写入也是线程安全的,因为i
每个任务的变量都是唯一的。
这段代码中不需要内存屏障(除了整个 Parallel.For 之前/之后,但可以假设这些)。
从您编号的项目来看,
Parallel.For() 暗示了 1) 和 4),
根本不需要 2) 和 3)。
归档时间: |
|
查看次数: |
461 次 |
最近记录: |