0

このテストから、動作がおかしいことに気付きました。外側のループをわずかに変更すると、たとえばゼロを追加すると、実行時間が約 15 ミリ秒から無限の時間に突然変わります。実行時間はまったく直線的に変化しません。それが永遠に続かない場合、せいぜい 30 ミリ秒であり、少なくともゼロです。スタックに割り当てられた配列に十分なスペースを確保するために、スタックサイズを数百万に設定したため、問題はスタックオーバーフローがスローされることではありません。とにかく、このコード [Visual Studio 2012 の場合、自動並列化とベクトル化をオンにして] をテストしてください。別のコンパイラを使用している場合は、#ifdef と #pragma を無視してください。

スタックの仮想 [予約] メモリと物理 [割り当て] メモリを 8000000 以上に設定し、それらを同じ数に設定しました。なんで?メモリを使い果たすことなく、1 ギガバイトまたは 2 ギガバイトの物理 RAM メモリをスタックに割り当てることができるのに、ディスクからメモリをプルアップまたはページングする必要がある理由がよくわかりません。

とにかく、ここにテスト コードがあります。ループと配列計算の無駄な時間がたくさんあります。リリース モードで実行され、速度が最適化されます。

#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS
#endif

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <malloc.h>

int 
main(void)
{
  clock_t       begin , end;
  double        time_spent;
  const int      *__restrict const arr1 = (int *)_alloca(300000 * sizeof(int));
  const int      *__restrict const arr2 = (int *)_alloca(300000 * sizeof(int));
  const int      *__restrict const arr3 = (int *)_alloca(300000 * sizeof(int));
  int            *__restrict const arr4 = (int *)_alloca(300000 * sizeof(int));

  begin = clock();
  {
    register int    i;
    /*
     * Add or remove a zero from this outer loop and note the
     * peculiar change in execution time.
     */
    for (i = 0; i < 200000; ++i) {
#pragma loop(hint_parallel(3))
#pragma loop(ivdep)
      for (i = 0; i < 300000; ++i) {
        arr4[i] = arr1[i] + arr2[i] * arr3[i] - i + arr1[i] + arr2[i] * arr3[i] - i - arr1[i] + arr2[i] * arr3[i] - i -
          -7 * arr1[i] + arr2[i] * arr3[i] - i + arr1[i] + arr2[i] * arr3[i] - i - arr1[i] + arr2[i] * arr3[i] +
          arr1[i] + arr2[i] * arr3[i] - i + arr1[i] + arr2[i] * arr3[i] - i - arr1[i] + arr2[i] * arr3[i];
      }
      arr4[2] = arr1[7] * arr4[888] - i;
      arr4[20000] += arr3[20000] - arr2[777] * i;
    }
  }
  end = clock();
  time_spent = (double)(end - begin) / CLOCKS_PER_SEC;

  printf("arr[4] as integer %i \n", arr4[2]);
  printf("Test1: time as a floating point type is %f \n", time_spent);
}
4

1 に答える 1

11

両方のループで同じループ変数 を使用してiいます。これは、最も内側のループが反復を完了した後、 300000 に等しいことを意味するため、最も外側のループは最初の反復i後に中断されます。ただし、最も外側のループの制限を増やすと、最も内側のループが再び実行され、再起動して再び 300000 のままになります。代わりに、最も外側のループで使用してください。ifor (int j = 0; j < 200000; ++j)

于 2013-05-29T22:06:27.087 に答える