我正在使用C#创建一个图像处理应用程序,并试图通过并行执行大量处理来利用我的多核系统。具体来说,我有一个Parallel.For循环遍历每个像素并应用高斯滤波器。只是执行计算,我看到了预期的显着加速,但是在尝试保存计算结果时会出现问题。代码看起来像这样:
Parallel.For(// various loop parameters
{
// processing and number crunching
// significant speed up here
.
.
.
bitmap.SetPixel(x, y, value);
});
这会产生运行时错误,因为多个线程最终会尝试同时写入位图对象。我按如下方式锁定了对象:
lock(bitmap)
bitmap.SetPixel(x, y, value);
但这最终比串行版慢。在检查之后,事实证明对SetPixel的调用占用了每次循环迭代的大约90%的运行时间,这意味着单独的线程花费大量时间等待获取位图对象的锁定,以及增加的开销有多个线程减慢了它的速度。
所以我想知道的是,有没有办法让多个线程同时写入同一个对象?我很小心每个线程都在处理图像的不同部分,因此不会引入任何竞争条件。是否有任何方法可以覆盖被抛出的错误并说“我知道我在做什么是不安全的,但我还是想这样做?”像Concurrency :: combinable这样的东西似乎可以解决这个问题,但这只是在C ++中。