C# 如何将Parallel.For转换为PLINQ Parallel.For(0,高度,新的并行选项{MaxDegreeOfParallelism=6},y=> { int currentLine=y*BMPData.Stride; 对于(int x=0;x
这基本上是一个并行代码,它将位图数据像素转换为灰色像素,但是有没有办法用并行Linq替换C# 如何将Parallel.For转换为PLINQ Parallel.For(0,高度,新的并行选项{MaxDegreeOfParallelism=6},y=> { int currentLine=y*BMPData.Stride; 对于(int x=0;x,c#,parallel-processing,parallel.foreach,plinq,C#,Parallel Processing,Parallel.foreach,Plinq,这基本上是一个并行代码,它将位图数据像素转换为灰色像素,但是有没有办法用并行Linq替换并行?我知道这没有什么意义,但它是特定赋值所必需的您可以使用Enumerable.Range和ForAll来获得类似的结果。尽管注意,ForAll不会以任何稳定的顺序处理列表-这可能适合您的用例 Parallel.For(0, Height, new ParallelOptions { MaxDegreeOfParallelism = 6 }, y => { int currentLine =
并行?我知道这没有什么意义,但它是特定赋值所必需的您可以使用Enumerable.Range
和ForAll
来获得类似的结果。尽管注意,ForAll
不会以任何稳定的顺序处理列表-这可能适合您的用例
Parallel.For(0, Height, new ParallelOptions { MaxDegreeOfParallelism = 6 }, y =>
{
int currentLine = y * BMPData.Stride;
for (int x = 0; x < Width; x = x + BPX)
{
var b = pixels[currentLine + x];
var g = pixels[currentLine + x + 1];
var r = pixels[currentLine + x + 2];
int avg = (r + g + b) / 3;
pixels[currentLine + x] = (byte)avg;
pixels[currentLine + x + 1] = (byte)avg;
pixels[currentLine + x + 2] = (byte)avg;
}
});
PLINQ简介文章中的段落有一个ForAll示例,ForAll似乎非常适合您的工作。此示例可以根据您的情况进行修改
Enumerable.Range(0,Height)
.AsParallel()
.WithDegreeOfParallelism(6)
.ForAll(y =>
{
/// existing code here
});
其中MakeGray是您的像素设置方法
这并没有比Jamiec的答案更好,但有更多的绒毛,这可能是你想要的,也可能不是
顺便说一句,我想你可以通过使用
平行。对于(0,宽度*高度/BPX,…)
或
Enumerable.Range(0,宽度*高度/BPX).aspallel()…
而
currentLine+x
将变成x
而不是可枚举的.Range(0,Height).AsParallel()
,一个等效的替代方法是:ParallelEnumerable.Range(0,Height)
。如果需要,可以使用AsOrdered()和.AsSequential(),@TheodorZoulias说:一个有序的序列仍然是并行处理的,但是它的结果是缓冲和排序的。@TheodorZoulias谢谢-我不知道并行可操作的AsOrdered
对所有的没有任何意义的影响-有一个是十年前写的,但是,它包含了很多关于何时使用共享状态的有价值的信息。这有一点——不修改共享状态的问题更容易并行化,这需要锁定。使用PLINQ,您可以生成一个具有平均颜色的新阵列,而无需使用。修改原件。您也可以执行一些非常重要的改进—图形转换非常常见,CPU可以通过在同一时间处理多个值来加速这些转换(例如SIMD、SSE、AVX)。例如,您可以使用一次添加三行的值,然后将每个元素除以。例如:var vR=newvector3(像素[x,y1],像素[x,y2],像素[y3]);。。。;var vAvg=(vR+vG_vB)/3代码>要获得3条线路的平均值,我认为可以使用并行消除第二个for循环。对于(0,宽度*高度/BPX,…)
和currentLine+x
将变成x
。消除第二个循环肯定会对性能产生负面影响。“当你做并行工作时,你不想让工作量变得太细。”西奥多·祖利亚斯同意,但OP说这是一项作业,所以我从学术角度来看待这一点。
var nums = Enumerable.Range(0, Height);
var query =
from num in nums.AsParallel().WithDegreeOfParallelism(6)
select num;
// Process the results as each thread completes
query.ForAll(e => MakeGray(e));