.net core 步长大于1的数组上的并行迭代

.net core 步长大于1的数组上的并行迭代,.net-core,f#,parallel.foreach,parallel.for,.net Core,F#,Parallel.foreach,Parallel.for,我正在做一个立体视觉的练习项目。这里的相关方面是,我有一个相当长的数组,表示图像中的每个像素,并希望在for循环的每次迭代中对数组中的每一个第二项执行一个操作-前一半项,然后在下一次迭代中对另一半项执行操作(这来自Felzenswalb&Huttenlocher在其2006年的论文“早期视觉的有效信念传播”中描述的优化)因此,您可以将其视为具有一个运行多次的外部for循环,并且对于该循环的每次迭代,我迭代数组中一半的条目 我希望像这样对数组进行并行迭代操作,因为我相信这样做是线程安全的,当然可能

我正在做一个立体视觉的练习项目。这里的相关方面是,我有一个相当长的数组,表示图像中的每个像素,并希望在for循环的每次迭代中对数组中的每一个第二项执行一个操作-前一半项,然后在下一次迭代中对另一半项执行操作(这来自Felzenswalb&Huttenlocher在其2006年的论文“早期视觉的有效信念传播”中描述的优化)因此,您可以将其视为具有一个运行多次的外部for循环,并且对于该循环的每次迭代,我迭代数组中一半的条目

我希望像这样对数组进行并行迭代操作,因为我相信这样做是线程安全的,当然可能更快。该操作涉及更新表示相邻像素的数据结构内的值,这些值本身并不用于给定的外循环迭代。Originally我只是一次迭代了整个数组,这意味着执行这项操作相当简单-我所需要做的就是在
数组
之间进行
并行
。iteri
。但是,更改为每秒钟操作一个数组条目更为棘手

为了从简单地对每个条目进行迭代更改,我从
Array.iteri(乐趣I p->…
更改为在startIndex..2..(ArrayLength-1)中对I使用
,其中startIndex为1或0,具体取决于我最后使用的是哪一个(通过切换布尔值控制).这意味着我不能简单地使用非常好的
.Parallel
使事情并行运行

关于如何在步长大于1的.NET中实现并行for循环,我还没有找到任何具体的方法。我能找到的最好方法是,但那一段只是对循环体中的索引转换作了模糊的说明。我不明白这是什么意思

我查看了和,以及,但这些似乎都不包括改变步长的选项

我想到的另一个选项是使用序列表达式,例如

let getOddOrEvenArrayEntries myarray oddOrEven =
    seq {
        let startingIndex =
            if oddOrEven then
                1
            else
                0
        for i in startingIndex..2..(Array.length myarray- 1) do
            yield (i, myarray.[i])
    }
然后使用
PSeq.iteri
from,但我不确定它是否能正确使用.NET Core 2.2。(请注意,目前至少我需要知道数组中给定元素的索引,因为它在处理过程中被用作另一个数组的索引)


如何并行迭代数组的每一秒元素?即使用大于1的步长迭代数组?

您可以尝试
PSeq.mapi
,它不仅提供序列项作为参数,还提供项的索引。 这里有一个小例子

let res = nums
                |> PSeq.mapi(fun index item -> if index % 2 = 0 then item else item + 1)

你也可以看看这个。只要确保用
PSeq

替换
Seq
,如果不测量它,通常几乎不可能知道一个解决方案是否比另一个更有效。(当然,除非一个是O(N),另一个是O(N^2),但我谈论的是同样大的O量级的解决方案)。我怀疑任何人都不能给你一个好的答案,除非他们已经遇到了你的确切情况并对其进行了基准测试。换句话说,这可能是你得到答案的方式。@Jarak因为你只关心偶数像素,你可以在
并行中从0迭代到
数组。长度/2
。For
。另一个选择是使用PLINQ的重载,它接受、索引并过滤掉奇数位置。这样可以并行搜索too@Jarak至于更改步长,通过
step
将索引从
0
增加到
N
,与在u之前从
0
迭代到
N/step
并将索引乘以
step
相同唱it@Jarak不过,请确保您确实对代码进行了基准测试。访问每秒钟一个像素将最终将所有数据加载到CPU的缓存中。您仍然只能处理一半的像素,但无法获得预期的4x/8x改进。另一方面,如果您在循环内根据索引执行不同的操作(奇数/偶数),您将只加载一次数据。我还鼓励测量性能,并将并行性能和简单但高效的顺序循环进行比较。有时抽象的开销太大,顺序循环结束得更快。谢谢。仅供参考,在查看您链接的采样片段时,我无意中发现了这一点做同样的事情。