我已经解决了这个问题。你能否解除我的禁令问题
答案 0 :(得分:2)
为了找到这方面的策略,有必要观察:
这意味着没有“大型并行化方案”可行。但是你可以对这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;
}