2012-08-26 97 views
2

我一直在尝试并行化以下功能,但无法弄清楚如何进行。线程简单计算

public static Cell GetClosestCell (Cell cell) 
{ 
    // The four calls below should be run in parallel. 
    Cell temp1 = new FindNorth(cell); 
    Cell temp2 = new FindSouth(cell); 
    Cell temp3 = new FindWest(cell); 
    Cell temp4 = new FindEast(cell); 

    // Return smallest cell based on [X]. 
    if ((temp1.X < temp2.X) && (temp1.X < temp3.X) && (temp1.X < temp4.X)) 
    { 
     return (temp1); 
    } 
    else if ((temp2.X < temp3.X) && (temp2.X < temp4.X)) 
    { 
     return (temp2); 
    } 
    else if (temp3.X < temp4.X) 
    { 
     return (temp3); 
    } 
    else 
    { 
     return (temp4); 
    } 
} 

四个函数调用中的每一个都应该并行运行,但不必启动一个线程。换句话说,应该有4个线程已经在等待输入,我可以发送每个呼叫。

我习惯了并行循环的正常范式,不知道如何处理这个问题(至少不是以一种干净的方式)。

+0

你说FindXxx需要很少的时间。如果是这种情况,则无法将4个步骤并行化:开销将始终支配有用的工作。在更高层次上并行化。 – usr

+0

我不能那样做。比这个函数更高的任何东西都是顺序的,并且取决于之前的迭代。没有办法保持4个线程的运行并轮询队列中的数据,一旦它变得可用,就进行处理。 –

+0

确定存在但是从该队列中取出通常会导致等待下一个项目(这通常需要旋转或OS同步(昂贵))。您的FindXxx方法有多快(每个核心每秒多少个呼叫)?如果他们速度太快,你就无能为力。极端的例子:你将如何并行两个整数加法?不可能。 – usr

回答

2
using System; 
using System.Threading.Tasks; 

public class Program { 
    public static void Main() { 

     Task<Cell> task1 = new Task<Cell>(n => FindNorth((Cell)n), cell); 

     Task<Cell> task2 = new Task<Cell>(n => FindSouth((Cell)n), cell); 
     Task<Cell> task3 = new Task<Cell>(n => FindSouth((Cell)n), cell); 
     Task<Cell> task4 = new Task<Cell>(n => FindEast((Cell)n), cell); 



     task1.Start(); 
     task2.Start(); 
     task3.Start(); 
     task4.Start(); 
     Console.WriteLine("Main method complete. Press <enter> to finish."); 
     Console.ReadLine(); 
    } 

} 
+1

+1,但我会在.NET 4.0中使用Task.Factory.StartNew(),在.NET 4.5中使用Task.Run()在单个操作中创建并启动Task。我还会在末尾添加'Task.WaitAll()'。闭包足以传递'cell'参数,不需要明确说明。 –

+0

谢谢。每次代码运行时,这不会创建4个线程吗?我想要的是在程序启动时启动4个线程,等待*处理单元。实际上,每个FindXXXX函数中的代码花费的时间很少,因此在每次调用时启动一个新线程都会挫败线程化的目的。 –

+1

@Raheel:不,任务的默认调度程序使用线程池,这意味着线程已经在运行;他们只接受工作要做。还有一些开销,如果你所做的工作量足够小,将这部分作品划分成小块可能不值得。相反,如果你有一堆'GetClosestCell'操作要执行,用'Parallel.ForEach(cells,cell => GetClosestCell(cell))'执行它们。 –