omp 并行循环的段错误
Segfault for omp parallel loop
我有一个二维浮点数组,我想对每一行的索引进行排序。我使用一个函数进行排序。我遍历数组的行并为每一行调用排序函数。我只想并行执行此函数调用。串行版本工作正常。但是当我使用 omp parallel 时,我得到了段错误。我已经尝试私有化变量并使几个循环变得关键,但我仍然无法理解此错误的根源。任何帮助将非常感激。
下面是我目前的代码:
#include <stdio.h>
#include <stdlib.h>
#include <omp.h>
void QuickSort(float A[], size_t I[], size_t lo, size_t hi)
{
while (lo < hi)
{
float pivot = A[I[lo + (hi - lo) / 2]];
size_t t;
size_t i = lo - 1;
size_t j = hi + 1;
while (1)
{
while (A[I[++i]] < pivot);
while (A[I[--j]] > pivot);
if (i >= j)
break;
t = I[i];
I[i] = I[j];
I[j] = t;
}
/* avoid stack overflow */
if((j - lo) < (hi - j)){
QuickSort(A, I, lo, j);
lo = j+1;
} else {
QuickSort(A, I, j + 1, hi);
hi = j;
}
}
}
//Declare number of data points
#define COUNT (10)
int main(int argc, char**argv)
{
int i,j;
//Index array for every row
size_t I[COUNT] ;
//Array to keep first 5 sorted indices for every row
size_t I_sorted[COUNT][5];
//Array to fill random values, and random float variable
float fr, A[COUNT][COUNT], B[COUNT] ;
srand((unsigned)time(NULL));
//Fill random float 2d array of COUNT*COUNT dimentions
for(i = 0; i < COUNT; i++) { // array of indexes
for(j=0; j<COUNT ;j++){
fr = (float)rand()/RAND_MAX;
A[i][j] = fr;
printf("%f\t",A[i][j]);
}
printf("\n");
}
//Need to call QuickSort count number of times in parallel
#pragma omp parallel for private(j)
for(i=0 ;i<COUNT; i++) {
//#pragma omp critical
//Assign a row of A to B to pass for sorting, also make index array
for(j=0 ;j<COUNT; j++) {
B[j] = A[i][j];
I[j] = j;
}
//Sort row indices
QuickSort(B, I, 0, COUNT-1);
//#pragma omp critical
//Store sorted indices
for(j=0;j<4; j++) {
I_sorted[i][j] = I[j];
//printf("%d\t",I_sorted[i][j]);
}
//printf("\n");
}
//Verify sorted array is correct
printf("------------------------\n");
for(i = 0; i < COUNT; i++) {
for(j = 0; j < 4; j++) {
printf("%d\t",I_sorted[i][j]);
}
printf("\n");
}
return(0);
}
串行代码工作正常,但使用 fopenmp 编译会出现段错误。
让我们考虑两个线程的情况。 for(i=0; i<COUNT; i++)
循环将分为两部分:一个线程将处理 0
...COUNT/2
范围内的 i
值,第二个线程将处理 i
值在 COUNT/2+1
...COUNT
范围内。两个线程将同时执行,并且您不能在没有同步的情况下从两个线程写入任何共享内存区域。 (如果他们确实写入相同的地址,这将是 https://en.wikipedia.org/wiki/Race_condition 并且它使程序不可预测。)
您的代码有数组 B
,它在两个线程中共享并被修改。这种同时访问是不正确的。尝试使用局部数组(在并行 for 循环的 { ... }
块内定义它,some docs)并检查其他变量以从两个线程进行写访问。
我有一个二维浮点数组,我想对每一行的索引进行排序。我使用一个函数进行排序。我遍历数组的行并为每一行调用排序函数。我只想并行执行此函数调用。串行版本工作正常。但是当我使用 omp parallel 时,我得到了段错误。我已经尝试私有化变量并使几个循环变得关键,但我仍然无法理解此错误的根源。任何帮助将非常感激。
下面是我目前的代码:
#include <stdio.h>
#include <stdlib.h>
#include <omp.h>
void QuickSort(float A[], size_t I[], size_t lo, size_t hi)
{
while (lo < hi)
{
float pivot = A[I[lo + (hi - lo) / 2]];
size_t t;
size_t i = lo - 1;
size_t j = hi + 1;
while (1)
{
while (A[I[++i]] < pivot);
while (A[I[--j]] > pivot);
if (i >= j)
break;
t = I[i];
I[i] = I[j];
I[j] = t;
}
/* avoid stack overflow */
if((j - lo) < (hi - j)){
QuickSort(A, I, lo, j);
lo = j+1;
} else {
QuickSort(A, I, j + 1, hi);
hi = j;
}
}
}
//Declare number of data points
#define COUNT (10)
int main(int argc, char**argv)
{
int i,j;
//Index array for every row
size_t I[COUNT] ;
//Array to keep first 5 sorted indices for every row
size_t I_sorted[COUNT][5];
//Array to fill random values, and random float variable
float fr, A[COUNT][COUNT], B[COUNT] ;
srand((unsigned)time(NULL));
//Fill random float 2d array of COUNT*COUNT dimentions
for(i = 0; i < COUNT; i++) { // array of indexes
for(j=0; j<COUNT ;j++){
fr = (float)rand()/RAND_MAX;
A[i][j] = fr;
printf("%f\t",A[i][j]);
}
printf("\n");
}
//Need to call QuickSort count number of times in parallel
#pragma omp parallel for private(j)
for(i=0 ;i<COUNT; i++) {
//#pragma omp critical
//Assign a row of A to B to pass for sorting, also make index array
for(j=0 ;j<COUNT; j++) {
B[j] = A[i][j];
I[j] = j;
}
//Sort row indices
QuickSort(B, I, 0, COUNT-1);
//#pragma omp critical
//Store sorted indices
for(j=0;j<4; j++) {
I_sorted[i][j] = I[j];
//printf("%d\t",I_sorted[i][j]);
}
//printf("\n");
}
//Verify sorted array is correct
printf("------------------------\n");
for(i = 0; i < COUNT; i++) {
for(j = 0; j < 4; j++) {
printf("%d\t",I_sorted[i][j]);
}
printf("\n");
}
return(0);
}
串行代码工作正常,但使用 fopenmp 编译会出现段错误。
让我们考虑两个线程的情况。 for(i=0; i<COUNT; i++)
循环将分为两部分:一个线程将处理 0
...COUNT/2
范围内的 i
值,第二个线程将处理 i
值在 COUNT/2+1
...COUNT
范围内。两个线程将同时执行,并且您不能在没有同步的情况下从两个线程写入任何共享内存区域。 (如果他们确实写入相同的地址,这将是 https://en.wikipedia.org/wiki/Race_condition 并且它使程序不可预测。)
您的代码有数组 B
,它在两个线程中共享并被修改。这种同时访问是不正确的。尝试使用局部数组(在并行 for 循环的 { ... }
块内定义它,some docs)并检查其他变量以从两个线程进行写访问。