【问题标题】:How many tasks should I use in .net according to the processor cores?根据处理器内核,我应该在 .net 中使用多少个任务?
【发布时间】:2014-05-05 13:23:39
【问题描述】:

我有一个 Pentium(R) 双核 CPU E5200 2/50GHz。

这意味着我有两个核心。我为智能算法开发了一种并行方法。

我通过将数据集分成 X 部分(X = .net 任务数)来进行数据并行处理。我为每个任务提供一组数据。

我尝试过使用 2、4、8 和 16 个任务,但我看不到算法有任何改进。当然,该算法的并行方法比串行(原始)方法更快,但是从 2 个任务开始到 16 个任务没有任何改进。他们都表现相同。我不知道天气我做错了什么,或者 CPU 容量这么大(任务数量是多少无关紧要?)。

为了更实用,这里是我的一些代码,描述了我实际在做什么:

  while (iteration < SOMState.Map.numbOfIterations)
        {
            netTasks.Clear(); // netTaks contains all the tasks that I creat inside the loop
            int tdd = 0;
            foreach (TasksData td in tasks)
            {
                int val = tdd;
                Task t1 = Task.Factory.StartNew(() => startParallelMethod(iteration, tasks[val], SOMState.dataset.GroupedData[val], tasks[val].Map, SOMState.dataset.GroupedDataDictionary[val]));
                netTasks.Add(t1);
                tdd++;
            }

         await Task.WhenAll(netTasks);
         // do some stuff here
         iteration++;
        }


    public void startParallelMethod(int iteration,TasksData task,List<GenerateDataSetFromCSV.Vector> dataset, Map map, Dictionary<int, List<Double>> dictionaryDataset)
    {
        // it performs some processing in here
    }

一项任务是否使用一个处理器核心?

Environment.ProcessorCount 给了我 2。这是否意味着无论任务数量是多少,性能仍然就像我使用了 2 个任务一样?!

更新:

对于那些可能感兴趣的人,我已经回答了我自己的问题。

【问题讨论】:

  • 您不能使用Parallel.ForEach等框架设施吗?您认为手动分配任务之间的工作会做得更好吗?
  • 提示:如果您的代码受 CPU 限制,您可以使用 Parallel.For / Parallel.Foreach 并让运行时决定它应该并行化的程度
  • 嗯,很有趣。好吧,我需要检查一下是否可以在我的代码中使用 Parallel.Foreach。谢谢你的回答:)
  • @Linky 我不能使用 Parallel.For 因为我在循环中使用了很多共享变量。更改代码并使其适应 Parallel.For 非常复杂

标签: parallel-processing


【解决方案1】:

作为 cmets 的后续行动:除非我遗漏了什么,而不是

int tdd = 0;
foreach (TasksData td in tasks)
{
    int val = tdd;
    Task t1 = Task.Factory.StartNew(() => startParallelMethod(iteration, tasks[val], SOMState.dataset.GroupedData[val], tasks[val].Map, SOMState.dataset.GroupedDataDictionary[val]));
    netTasks.Add(t1);
    tdd++;
}

你可以写(请注意:伪代码!)

Parallel.For(0, tasks.Length, val => { 
    startParallelMethod(iteration, tasks[val], SOMState.dataset.GroupedData[val], tasks[val].Map, SOMState.dataset.GroupedDataDictionary[val])
});

由于您的原始代码使用 await 您可以将 Parallel.For 代码包装在 Task.Run() 中,并且它的行为在方法之外应该是相同的(尽管这与您的初始示例相同,远离最佳实践关于使用异步等待)。

尽管如此 - 只需进行少量更改,您应该能够让运行时决定使用多少任务。

【讨论】:

  • 我认为这是相同的,因为“任务”是我要使用的任务数(用户定义)。根据 tasks.count,我将庞大的数据集拆分为 tasks.count 组。然后,将每组数据 (SOMState.dataset.GroupedData[val]) 作为参数提供给方法 startParallelMetho。该方法将处理作为参数给出的数据组。如果我有 n 个任务,这意味着我将使用 n 个不同的数据集(数据组)调用 startParallelMethod n 次。
  • 为了更清楚,startParallelMethod 将被调用 tasks.count 次和 tasks.count 来自 tasks.count .net 任务的不同数据。
  • 也许我没有正确理解原始问题:似乎在原始代码中 startPArallelMethod 是使用 Task.Factory.StartNew 并行执行的。 All 在所有 tasks.Count 运行 startParallelMethod 的任务将被启动。到目前为止这是正确的吗?取而代之的是,使用 Parallel.For 会做几乎相同的事情 - 运行 startParallelMethod task.Count 次 - 除了它负责同时启动/运行的数量。这不是问题所在吗?
  • 是的,你说的都是真的。我的问题是:“任务数”应该是多少,换句话说,这意味着“我应该将原始数据集分成多少组”?我有一个数据集(SOMState.dataset)并且为了并行化我的算法我将其拆分为 tasks.count 组 (SOMState.dataset.GroupedData)。如果我将原始数据集分成 4 个组。我从 4 个不同的任务中调用 startParallelmethod 4 次。通过这种方式,我试图通过将我的数据集拆分为 4 个 .net 任务来更快地执行算法。每个任务将执行一组原始数据集
  • 我理解你所说的一切,我会使用你的建议。我的问题是我应该使用的子组(原始数据集)的数量。如果我使用 n 分组,则 Parallel.for 将循环 n 次!那是我的问题。我认为这取决于处理器的核心数量。也许我应该使用 Environment.ProcessorCount 组数据。这意味着 Parallel.For 循环将循环 Environment.ProcessorCount 次。
【解决方案2】:

对于那些可能感兴趣的人:

在进行了一些实验之后,以下是使用 i7 处理器的结果。它表明使用 6 个任务(处理器的核心数)执行得最快。当我说使用 6 个任务时,我的意思是把我的数据集分成 6 个组;每个小组将被分配到一项任务。我们也可以使用 Parallel.For 作为我接受的答案。

在图像中,显示了不同数据集(不同数量的输入)的结果。从 5000 到 100000 个输入数据和不同数量的任务。您可以轻松地发现(从表格中,或者您可以自己尝试)如果您使用 Environment.ProcessorCount 任务执行速度最快。

作为结论,结果表明使用 Environment.ProcessorCount 是一种很好的做法。然后每个 .NET 任务将处理(独立于程序员)它将创建的线程数(在后台)。

附: Environment.ProcessorCount 返回整数值(处理器的核心数)。 “数据组”也意味着创建的任务数

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-12-29
    • 1970-01-01
    • 1970-01-01
    • 2011-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多