Parallel processing 如何在C中并行化循环

Parallel processing 如何在C中并行化循环,parallel-processing,Parallel Processing,我已经解决了这个问题。您能否释放我的ban问题您不希望并行线程访问相同的内存,因此您可以创建一个访问偶数内存位置的循环,以及另一个访问奇数内存位置的循环: /* 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; } /*偶数*/ 对于(i=0;i是什么让你得出这样的结论:线程在这里确实有帮助?你对

我已经解决了这个问题。您能否释放我的ban问题

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

/* 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;
}
/*偶数*/

对于(i=0;i是什么让你得出这样的结论:线程在这里确实有帮助?你对你的代码进行了基准测试吗?这段代码是你计算的热点吗?过早优化是万恶之源

我不确定线程技术是否能帮助您进行
100000
迭代计算。您可以尝试。但是,请做一个基准测试,以验证它是否适合您的情况。您一定要避免错误共享,以充分利用硬件


退一步,看一看全貌。您的算法是否有问题?代码中真正的热点是什么?对其进行基准测试,然后解决问题。

为了找到解决此问题的策略,请注意:

  • 操作前数组的内容未知
  • 数组元素的数据类型未知,但已知支持整数加法。这意味着不能假定对数组元素的并发操作是正确的
  • 最后一个包含1000个元素的块(a[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;
     });
}
typedef struct Range_标记{From:int;To:int}Range_t;
INTA[101000];
对于(b=1000;b<101000;b+=1000)
{
工作范围[10]={b,b+100},{b+100,b+200},{b+900;b+1000};
并行运行(作业,10,[&a](范围作业){
对于(i=job.From;i
替代解决方案:

对1000个子集的操作:0..999中i的s_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()
let a=Array.init 101000(乐趣i->i)
管闲事=
[|0..999|]
|>Array.Parallel.iter
(乐趣s->
因为我在1..100做
设枢轴=s+1000*i

a、 [pivot]什么是“特定代码转换”您想应用的?@dasblinkenlight只需更改代码的某些部分,就可以允许它并行化错误共享大量?为什么这样做会有帮助?当编译器无法将代码转换为合理的代码时,您甚至可能会降低性能,因为当第二个循环启动时,CPU必须从一开始就重新获取缓存线gins和从头开始。你能用一个参考或一些文档来证明你的陈述吗?正如我在帖子中提到的,这取决于你需要什么。为什么你甚至需要线程?这个循环不可能是通过线程处理的时间关键。如果是,那么试试OpenMP。这是学校的练习还是什么问这里?问这个问题是没有成效的。毕竟,这可能是一项研究,而不是一个实际问题。你可以在1000个元素的块中对此进行并行处理。我不这么认为。我不能回答他的评论,因为答案取决于更多的信息。关于线程的研究,或者仅仅理解线程的概念for循环与修复特定for循环完全是两码事。当然你可以优化它,但无论如何循环都会被优化掉。那么你想在这里穿插什么呢?因此我添加了一些问题以获得更清晰的画面并给他更好的答案。那么这有什么错?@HelloWorld欢迎来到现实生活中!:)每当你收到一份不完整的规范时,你总是要从某种程度上开始。典型的程序是你自己写一份文档,根据你得到的事实,指定你将构建什么。然后,对话开始……这不是重点。如果这是一项研究或只是一项练习,我可以假设他知道如何构建处理他得到的信息。如果是生产中的代码片段,我希望上下文能够帮助他。如果有人怀疑在正确的上下文中使用循环是没有帮助的,就告诉他如何执行循环。