1

関数を変換して、C# でシーケンシャルではなく並列に実行しようとしていますが、何が間違っているのかわかりません。

// sequential
static void Romberg(double a, double b, int n, double[,] R)
{
    int i, j, k;
    double h, sum;

    h = b - a;
    R[0, 0] = (h / 2) * (f(a) + f(b));

    for (i = 1; i <= n; i++)
    {
        h = h / 2;
        sum = 0;

        for (k = 1; k <= (Math.Pow(2.0, i) - 1); k += 2)
        {
            sum += f(a + k * h);
        }

        R[i, 0] = R[i - 1, 0] / 2 + sum * h;

        for (j = 1; j <= i; j++)
        {
            R[i, j] = R[i, j - 1] + (R[i, j - 1] - R[i - 1, j - 1]) / (Math.Pow(4.0, j) - 1);
        }
    }
}


// parallel
static void RombergCP(double a, double b, int n, double[,] R)
{
    int i,j, k;
    double h, sum;

    h = b - a;
    R[0, 0] = (h / 2) * (f(a) + f(b));

    Parallel.For(0, n, options, i =>
    {
        h = h / 2;
        sum = 0;

         for (k = 1; k <= (Math.Pow(2.0, i) - 1); k += 2)
        {
            sum += f(a + k * h);
        };

        R[i, 0] = R[i - 1, 0] / 2 + sum * h;

        for (j = 1; j <= i; j++)
        {
            R[i, j] = R[i, j - 1] + (R[i, j - 1] - R[i - 1, j - 1]) / (Math.Pow(4.0, j) - 1);
        }
    });
}

私が得ているエラーは、「親または現在の」スコープで使用される「i」に別の意味を与えるため、「i」を宣言できないということです。並列関数で名前を i2 に変更しようとしましたが、同じエラーが発生します。前もって感謝します!

4

2 に答える 2

2

int i最上部の宣言を削除します。以下のラムダによって宣言されます。

于 2012-05-12T09:48:27.663 に答える
1

いくつかの問題:

  • 可能な限り最小のスコープで変数を宣言します。

  • あなたの外側のループは からfor (i = 1; i <= n; i++)に行きます。Parallel.For(0, n, options, ...)つまりR[i-1, ...]、Parallel バージョンがスローされます。

  • h = h / 2;スレッドセーフではありません。


// parallel
static void RombergCP(double a, double b, int n, double[,] R)
{
  //int i,j, k;
  //double h, sum;

  double h0 = b - a;
  R[0, 0] = (h0 / 2) * (f(a) + f(b));

  Parallel.For(1, n, options, i =>   // start at 1
  {
     //h = h / 2;
     double h = (b - a) / Math.Pow(2, i);    // derive from i
     double sum = 0;

     for (int k = 1; k <= (Math.Pow(2.0, i) - 1); k += 2)   // keep k local
       ...
于 2012-05-12T09:56:22.793 に答える