0

私は、Stampede を通じて Xeon Phi を使用して Collat​​z Conjecture 問題に取り組んでいます。コードがテストされ、最大 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

完全なコードは github hereで見つけることができますが、まだ多くの効率の問題がありますが (ベクトル化サポートを使用できます)、私が現在着陸したのはこれです ( 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 に答える
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 に答える