我有一个for循环,每次迭代几乎完全独立于每个其他迭代。我做了一些初步的OpenMP试验,看看我是否可以加快速度。使用一个简单的指令,我的速度增加了三到四倍。代码类似于此:
#pragma omp parallel for default(none) shared(ptr1,ptr2) firstprivate(const2,k,inc,max)
for(i = 0; i < max; i += inc)
{
float *ptr1_ = (*ptr1)[i>>k][0];
float v = ptr2[i/const2];
// do stuff with data
}
然后我开始优化单线程代码。在这个过程中,我发现我可以增加指针而不是索引它们,无论出于什么原因,这都会产生合理的速度提升。现在的问题是,我无法想出一个简单的方法来告诉OpenMP每个线程指针的起始位置。基本上,我想出的是以下内容。
#pragma omp parallel default(none) shared(ptr1,ptr2) firstprivate(const1,inc,max)
{
int chunk = max / (omp_get_num_threads()*inc);
chunk = (chunk < 1)? 1: chunk;
float *ptr1_ = &(*ptr1)[0][0] + chunk*omp_get_thread_num()*const1;
float *ptr2_ = ptr2 + chunk*omp_get_thread_num();
#pragma omp for schedule(static,chunk)
for(i = 0; i < max; i += inc)
{
// do stuff with data
ptr1_ += const1;
ptr2_++;
}
}
这似乎有效,虽然我花了一些时间来弄清楚如何计算指针偏移,因为inc不是一个,我不确定这是如何影响chunk的意义的。此外,我不太自信它在边缘情况下正常工作(当max很小或不是num_threads * inc的整数倍时)。此外,代码更加复杂,并且直接调用omp函数,我之前不必依赖它们。最后,通过强制调度方法和块大小,我限制了OpenMP实现的潜在优化。
所以我的问题是,有没有办法在循环开始时获取线程的循环索引,所以我不必以这种复杂的方式手动计算指针偏移量?