如何在C中并行化循环

时间:2015-09-18 23:18:31

标签: parallel-processing

我已经解决了这个问题。你能否解除我的禁令问题

3 个答案:

答案 0 :(得分:2)

为了找到这方面的策略,有必要观察:

  • 操作前阵列的内容未知。
  • 数组元素的数据类型未知,但已知支持添加整数。这意味着,不能假设对阵列元素的并发操作是合理的。
  • 1000个元素的最后一个块(一个[100000..100999])只能在上一个1000块处理后处理。依此类推,直到第一个块(a [1000..1999])。

这意味着没有“大型并行化方案”可行。但是你可以对这1000个元素块进行分区,并对它们进行并行处理。

typedef struct Range_tag { From : int; To : int } Range_t;
int a[101000];
for( b = 1000; b < 101000; b+=1000)
{
     Range_t jobs[10] = { {b,b+100}, {b+100,b+200}, ... {b+900; b+1000} };
     run_parallel(jobs,10,[&a](Range_t job) { 
         for( i = job.From; i < job.To; i++ ) a[i] = a[i-1000]+1;
     });
}

替代解决方案:

1000个子集的操作:s_i:0..999中i的[a [i],a [i + 1000],...]是正交的。所以你也可以为这些股票安排1000个工作岗位。

在f#中,它看起来像这样:

let a = Array.init 101000 (fun i -> i)
let meddle() =
    [|0..999|]
    |> Array.Parallel.iter
        (fun s ->
            for i in 1..100 do
                let pivot = s + 1000 * i
                a.[pivot] <- a.[pivot-1000] + 1
        )
meddle()

答案 1 :(得分:1)

是什么让您得出线程在这里有帮助的结论?您是否对代码进行了基准测试?这段代码是你计算的热点吗?过早的优化是万恶之源!

我不确定线程​​是否可以帮助您进行100000次迭代计算。您可以尝试OpenMP。但是做一个基准来验证它适合你的情况。你必须避免虚假共享才能充分利用你的硬件。

退后一步,看看整个画面。你的算法有问题吗?你代码中真正的热点是什么?对其进行基准测试,然后解决问题。

答案 2 :(得分:-1)

您不希望并行线程访问相同的内存,因此您可以创建一个访问偶数内存位置的循环,以及另一个访问奇数内存位置的循环:

/* even */
for(i = 0;i<100000;i+=2)
{
 a[i+1000] = a[i] +1;
}

/* odd */
for(i = 1;i<100000;i+=2)
{
 a[i+1000] = a[i] +1;
}