我有一个算法将拜耳图像通道转换为RGB.在我的实现中,我有一个嵌套for循环,它遍历拜耳通道,从拜耳索引计算rgb索引,然后从拜耳通道设置该像素的值.这里要注意的主要事实是每个像素可以独立于其他像素计算(不依赖于先前的计算),因此该算法是并行化的自然候选者.但是,计算依赖于某些预设数组,所有线程将在同一时间访问但不会更改.
然而,当我尝试将主要for与MS 并行化时,我的cuncurrency::parallel_for性能没有提升.事实上,对于在4核CPU上运行的大小为3264X2540的输入,非并行化版本在~34ms内运行,并行化版本运行在~69ms(平均超过10次运行).我确认该操作确实是并行化的(为该任务创建了3个新线程).
使用英特尔的编译器提供tbb::parallel_for了接近完全的结果.为了比较,我开始使用这个算法实现,C#其中我也使用了parallel_for循环,在那里我遇到了接近X4的性能提升(我选择了C++因为这个特定任务C++即使使用单个核心也更快).
有什么想法阻止我的代码很好地并行化?
我的代码:
template<typename T>
void static ConvertBayerToRgbImageAsIs(T* BayerChannel, T* RgbChannel, int Width, int Height, ColorSpace ColorSpace)
{
//Translates index offset in Bayer image to channel offset in RGB image
int offsets[4];
//calculate offsets according to color space
switch (ColorSpace)
{
case ColorSpace::BGGR:
offsets[0] = 2;
offsets[1] = 1;
offsets[2] = 1;
offsets[3] = 0;
break;
...other color spaces
}
memset(RgbChannel, …Run Code Online (Sandbox Code Playgroud) TParallel.For()有一个称为的论点AStride.在我的情况下,AStride是2:
TParallel.&For(2, 1, 10,
procedure(index: Integer)
begin
TThread.Queue(nil,
procedure
begin
memo1.Lines.Add(index.ToString());
end
);
end
);
Run Code Online (Sandbox Code Playgroud)
我在这里无法理解"AStride"的技术含义.是否AStride = 2意味着第一个线程将处理该范围内的两个连续数字[1..10],第二个线程将处理下一个连续数字等?
**英语不是我的母语,我将"Stride"翻译为"long step"或"pace".
我需要ThreadPool每晚运行大约1,000个任务(这个数字可能会在未来增长).每个任务都执行长时间运行的操作(从Web服务读取数据),并且不是CPU密集型的.Async I/O不是这个特定用例的选项.
给定一个IList<string>参数,我需要DoSomething(string x).我试图在以下两个选项之间进行选择:
IList<Task> tasks = new List<Task>();
foreach (var p in parameters)
{
tasks.Add(Task.Factory.StartNew(() => DoSomething(p), TaskCreationOptions.LongRunning));
}
Task.WaitAll(tasks.ToArray());
Run Code Online (Sandbox Code Playgroud)
要么
Parallel.ForEach(parameters, new ParallelOptions {MaxDegreeOfParallelism = Environment.ProcessorCount*32}, DoSomething);
Run Code Online (Sandbox Code Playgroud)
哪个选项更好,为什么?
注意 :
答案应包括使用TaskCreationOptions.LongRunning和的比较MaxDegreeOfParallelism = Environment.ProcessorCount * SomeConstant.
这是一个控制台程序,希望10个线程批量启动,等待5秒,然后批量停止.
static void Main(string[] args)
{
System.Threading.Tasks.Parallel.For(0, 10, (index) =>
{
Action<int> act = (i) =>
{
Console.Write("start {0} ", i);
Thread.Sleep(5000);
};
act.BeginInvoke(index, OnTaskComplete, index);
});
Console.ReadKey();
}
static void OnTaskComplete(IAsyncResult res)
{
Console.Write("finish {0} ", res.AsyncState);
}
Run Code Online (Sandbox Code Playgroud)
但结果不是我的预期,10个线程一个接一个地慢慢开始(大约1秒间隔),甚至一些"完成"在一些"开始"之前出现.
当注释掉Thread.Sleep时,所有线程都在flash中开始和结束.
会Thread.Sleep影响其他线程吗?无论如何要做一个纯粹的空闲时间?
/ - - - - - - - - - - - - - - -编辑 - - - - - - - - - - ----------
同样的问题也发生在:
static void Main(string[] args)
{
System.Threading.Tasks.Parallel.For(0, 10, (index) …Run Code Online (Sandbox Code Playgroud) 我已经习惯在.Net的并行扩展中使用Parallel.For(),因为它是一种简单的并行化代码的方法,而无需手动启动和维护线程(这可能是繁琐的).我现在正在看一个无限循环(做一些事情,直到我发出信号停止),我希望并行化,没有一个参数可以自由Parallel.For()重载这样做,所以想知道这里最好的方法是什么是.原则上我可以这样做:
Parallel.For(0, int.Max)
Run Code Online (Sandbox Code Playgroud)
但我怀疑这可能不是工作分区逻辑处理的预期/有效模式(?)
另一种选择是:
for(;;)
{
Parallel.For(0, 128, delegate()
{
// Do stuff.
}
}
Run Code Online (Sandbox Code Playgroud)
但这似乎不够优雅,也可能导致低效的工作分区.
现在我的直觉是通过创建和维护我自己的线程来手动执行此操作,但我有兴趣获得一些反馈/意见.谢谢.
===更新===
我在接受的答案中使用了文章中的代码的简化版本(我删除了ParallelOptions参数).这是代码......
public class ParallelUtils
{
public static void While(Func<bool> condition, Action body)
{
Parallel.ForEach(IterateUntilFalse(condition), ignored => body());
}
private static IEnumerable<bool> IterateUntilFalse(Func<bool> condition)
{
while (condition()) yield return true;
}
}
Run Code Online (Sandbox Code Playgroud)
一个示例用法是:
Func<bool> whileCondFn = () => !_requestStopFlag;
ParallelUtils.While(whileCondFn, delegate()
{
// Do stuff.
});
Run Code Online (Sandbox Code Playgroud) .net c# parallel-processing parallel-extensions parallel-for
我想在我的项目(WPF)中使用并行编程.这是我的for循环代码.
for (int i = 0; i < results.Count; i++)
{
product p = new product();
Common.SelectedOldColor = p.Background;
p.VideoInfo = results[i];
Common.Products.Add(p, false);
p.Visibility = System.Windows.Visibility.Hidden;
p.Drop_Event += new product.DragDropEvent(p_Drop_Event);
main.Children.Add(p);
}
Run Code Online (Sandbox Code Playgroud)
它没有任何问题.我想用Parallel.For写它,我写了这个
Parallel.For(0, results.Count, i =>
{
product p = new product();
Common.SelectedOldColor = p.Background;
p.VideoInfo = results[i];
Common.Products.Add(p, false);
p.Visibility = System.Windows.Visibility.Hidden;
p.Drop_Event += new product.DragDropEvent(p_Drop_Event);
main.Children.Add(p);
});
Run Code Online (Sandbox Code Playgroud)
但是在producd类的构造函数中出现错误
调用线程必须是STA,因为许多UI组件都需要这个.
那么我使用了Dispatcher.这是代码
Parallel.For(0, results.Count, i =>
{
this.Dispatcher.BeginInvoke(new Action(() =>
product p = new product();
Common.SelectedOldColor = p.Background; …Run Code Online (Sandbox Code Playgroud) 我正在尝试开始在 C 中使用基本的 OpenMP 功能。我对“omp parallel for”的基本理解使我相信以下应该在线程之间分配以下循环迭代并且应该并发执行。我得到的输出如下。代码如下。在我的 hello world 示例中是否缺少一些微妙的东西?
来自 omp 线程的 Hello World 0 来自 omp 线程的 Hello World 0 来自 omp 线程的 Hello World 0 来自 omp 线程的 Hello World 0 来自 omp 线程的 Hello World 0 来自 omp 线程 0 的 Hello World 等等。
int HelloFunc()
{
int i;
int numthreads = 8;
#pragma omp parallel for default(none) num_threads(numthreads) private(i)
for (i = 0; i < 100; i++)
{
int tid = omp_get_thread_num();
printf("Hello world from …Run Code Online (Sandbox Code Playgroud) // parameters.Count == 10
// actualFreeLicenses == 2
Parallel.For(0, parameters.Count, new ParallelOptions()
{
MaxDegreeOfParallelism = actualFreeLicenses
}, i =>
{
ExternalProgram(i);
}
);
Run Code Online (Sandbox Code Playgroud)
当我执行上面的代码时,我注意到i传递给ExternalProgram方法的值是1和6,后来的2和7,后来的3和8 ......
如果我有14个参数和2个许可证,它总是启动1和8,后来的2和9 ......
是否可以定义顺序:首先是1和2,后来是3和4等?
并行for for .net 4.0是否自动获得GPU计算的特权?或者我必须配置一些驱动程序,以便它使用GPU.
我正在尝试使用parallel_for,但出现错误,代码为:
#include "stdafx.h"
#include <iostream>
#include <windows.h>
#include <ppl.h>
using namespace std;
using namespace concurrency;
int _tmain(int argc, _TCHAR* argv[])
{
parallel_for(size_t(0), 50, [&](size_t i)
{
cout << i << ",";
}
cout << endl;
getchar();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
错误是:
IntelliSense:没有重载函数“ parallel_for”的实例与参数列表匹配>参数类型为:(size_t,int,lambda [] void(size_t i)-> void
这仅是示例,我必须在更大的项目中使用它,但首先,我想了解如何正确使用它。
* 编辑 *
我将代码更改为:
parallel_for(size_t(0), 50, [&](size_t i)
{
cout << i << ",";
});
Run Code Online (Sandbox Code Playgroud)
但仍然出现恼人的错误:IntelliSense:没有重载函数“ parallel_for”的实例与参数列表匹配,参数类型为:(size_t,int,lambda [] void(size_t i)-> void)