0

我正在通过 Stampede 使用 Xeon Phi 解决 Collat​​z 猜想问题。我已经测试了我的代码已经过测试并且对于高达 100,000 的值可以正常工作,但是测试高达 100 万的值时,我几乎立即收到了分段错误(“SIGSEV”)。几天来我一直在用头撞墙,但根本无法弄清楚这个错误。任何帮助都非常感谢。

typedef unsigned long long bigInt;

// Number to test to (starting from 1)
   #define bigSize     100000

typedef struct {
    int numSteps;
    bigInt stopPoint;
} batcher;

typedef struct {
    bigInt num;
    batcher to_batch;
} to_ret;
int main () {
    //Stores values as [num][#steps to smaller val][smaller val]
    to_ret retlist[bigSize];
    //Stores values as [#steps to smaller val][smaller val], sorted by num
    batcher results[bigSize];
    ...

    #pragma offload target(mic:0) inout(retlist) shared(retlist)
    {
        #pragma omp parallel for
        for(i = 1; i < bigSize; i++){
            retlist[i].num = i + 1;
            bigInt next = retlist[i].num;
            int count = 0;

            do {
                count++;

                if (next%2 == 1)
                    next=(3*next+1)/2;
                else
                    next/=2;

            } while(next > retlist[i].num);

            retlist[i].to_batch.numSteps = count;
            retlist[i].to_batch.stopPoint = next;
        }
    }

    ///Organizes data into a sorted array
    #pragma omp parallel for
    for (i = 0; i < bigSize; i++){
        results[retlist[i].num - 1] = retlist[i].to_batch;
    }
    ...
}

我非常有信心问题会出现在上面的代码段中。

4

2 回答 2

0

以下代码正确编译:

  • 不会溢出堆栈
  • 不会用一堆结构的 typedef 混淆代码
  • 不会隐藏 bigNum 是 unsigned long long int。

  • 确实包括索引变量“i”的声明

我无法访问优化编译指示,所以暂时将它们注释掉。

//typedef unsigned long long bigInt;

// Number to test to (starting from 1)
#define bigSize     (100000)

struct batcher
{
    int numSteps;
    //bigInt stopPoint;
    unsigned long long stopPoint;
};

struct to_ret
{
    //bigInt num;
    unsigned long long num;
    struct batcher to_batch;
};

//Stores values as [num][#steps to smaller val][smaller val]
static struct to_ret retlist[bigSize];
//Stores values as [#steps to smaller val][smaller val], sorted by num
static struct batcher results[bigSize];

int main ()
{
    int i;
    // more code here

    ////#pragma offload target(mic:0) inout(retlist) shared(retlist)
    {
        ////#pragma omp parallel for
        for(i = 1; i < bigSize; i++)
        {
            retlist[i].num = i + 1;
            //bigInt next = retlist[i].num;
            unsigned long long next = retlist[i].num;
            int count = 0;

            do
            {
                count++;

                if (next%2 == 1)
                    next=(3*next+1)/2;
                else
                    next/=2;

            } while(next > retlist[i].num);

            retlist[i].to_batch.numSteps = count;
            retlist[i].to_batch.stopPoint = next;
        }
    }

    ///Organizes data into a sorted array
    ////#pragma omp parallel for
    for (i = 0; i < bigSize; i++){
        results[retlist[i].num - 1] = retlist[i].to_batch;
    }
    // more code here

    return(0);
} // end function: main
于 2014-12-21T04:47:14.483 回答
0

完整的代码可以在 github 上找到虽然它仍然存在很多效率问题(可以使用矢量化支持),但我目前得到的是这个(利用barak-manos的建议):

typedef unsigned long long bigInt;

/// Number to test up to (starting from 1)
#define bigSize     1000000000 //340282366920938463463374607431768211455

typedef struct {
    int numSteps;
    bigInt stopPoint;
} batcher;

typedef struct {
    bigInt num;
    batcher to_batch;
} to_ret;

__attribute__((target(mic))) to_ret retlist[bigSize]; ///Stores values as [num][#steps to smaller val][smaller val]
__attribute__((target(mic))) batcher results[bigSize]; ///Stores values as [#steps to smaller val][smaller val] & is sorted by num


int main () {
    bigInt j;
    double start, end;

    retlist[0].num = 1; retlist[0].to_batch.numSteps = 0; retlist[0].to_batch.stopPoint = 1;
    start = omp_get_wtime();

    #pragma offload target(mic:0) out(results)
    {
        int count;
        bigInt i, next;

    #pragma omp parallel for
        for(i = 1; i < bigSize; i++){
            next = retlist[i].num = i + 1;
            count = 0;

            do {
                count++;

                if (next%2 == 1)
                    next=(3*next+1)/2;
                else
                    next/=2;

            } while(next > retlist[i].num);

            retlist[i].to_batch.numSteps = count;
            retlist[i].to_batch.stopPoint = next;
        }

    ///Organizes data into a sorted array
    #pragma omp parallel for
    for (i = 0; i < bigSize; i++){
        results[i] = retlist[i].to_batch;
    }
  }
...

    for(j = 0; j < bigSize; j++){
        results[j].numSteps += results[results[j].stopPoint-1].numSteps;
    }

    return(0);
}

如果有人感兴趣,请随时为我的项目创建一个分支。

于 2014-12-22T05:19:56.197 回答