1

クラスメートの何人かが、過去数日間、StackOverflow で同じ課題について実際に質問しようとしていることに気付きました。そのため、削除された 1 つの質問のコンテキスト (ただし、まだキャッシュされている) を恥知らずにコピー ペースト (のみ) します。 Google で回答なし) を使用して時間を節約できます。あらかじめお詫び申し上げます。

コンテキスト
システムの L2 キャッシュのデータ スループット (MB/秒) を測定する C プログラムを作成しようとしています。測定を実行するには、配列 A を配列 B にコピーし、複数回繰り返し、スループットを測定するプログラムを作成する必要があります。

少なくとも 2 つのシナリオを検討してください。

  • 両方のフィールドが L2 キャッシュに収まります
  • 配列のサイズは、L2 キャッシュのサイズよりも大幅に大きくなっています。

string.h から memcpy() を使用して配列をコピーし、両方の配列をいくつかの値 (たとえば、rand() を使用した乱数) で初期化し、少なくとも 100 回繰り返します。そうしないと、違いがわかりません。

配列のサイズと繰り返しの数は、入力パラメーターである必要があります。配列サイズの 1 つは、L2 キャッシュ サイズの半分にする必要があります。

質問
課題のコンテキストに基づいて、私が何をする必要があるかについて良い考えを持っています。問題は、作業用のテンプレート コードが提供されたのですが、その一部を解読するのに苦労していることです。誰かが何が起こっているのかを理解するのを手伝ってくれたら本当にありがたい.

コードは次のとおりです。

/* do not add other includes */
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <time.h>
#include <string.h>

double getTime(){
  struct timeval t;
  double sec, msec;

  while (gettimeofday(&t, NULL) != 0);
  sec = t.tv_sec;
  msec = t.tv_usec;

  sec = sec + msec/1000000.0;

  return sec;
}

/* for task 1 only */
void usage(void)
{
    fprintf(stderr, "bandwith [--no_iterations iterations] [--array_size size]\n");
    exit(1);
}

int main (int argc, char *argv[])
{
  double t1, t2; 

  /* variables for task 1 */
  unsigned int size = 1024;
  unsigned int N = 100; 
  unsigned int i;

  /* declare variables; examples, adjust for task */
  int *A;
  int *B;


  /* parameter parsing task 1 */
  for(i=1; i<(unsigned)argc; i++) {
    if (strcmp(argv[i], "--no_iterations") == 0) {
      i++;
      if (i < argc)
        sscanf(argv[i], "%u", &N);
      else
        usage();
    } else if (strcmp(argv[i], "--array_size") == 0) {
      i++;
      if (i < argc)
        sscanf(argv[i], "%u", &size);
      else
        usage();
    } else usage();
  }


  /* allocate memory for arrays; examples, adjust for task */
  A = malloc (size*size * sizeof (int));
  B = malloc (size*size * sizeof (int));



  /* initialise arrray elements */    




  t1 = getTime();

  /* code to be measured goes here */



  t2 = getTime();


  /* output; examples, adjust for task */
  printf("time: %6.2f secs\n",t2 - t1);

  /* free memory; examples, adjust for task */
  free(B);
  free(A);

  return 0;  
}

私の質問は次のとおりです。

  • 使用方法の目的は何ですか?
  • 私が知る限り、それは常に使用法()につながり、sscanf行でパラメーターを取りません。
  • この割り当てでは、配列のサイズを KB または MB で記録することを意図しています。malloc はサイズをバイト単位で割り当て、size変数値が 1024 の場合は 1MB * sizeof(int) になることがわかっています (少なくとも)。この場合、記録する必要がある配列サイズは 1MB または 1MB * sizeof(int) でしょうか?
  • パラメータの受け渡しが適切に機能し、パラメータを渡してsize変数の値を変更した場合、配列のサイズは常にsize変数の 2 乗になりますか? sizeそれとも、配列のサイズは単なる変数と見なされますか? これらすべてについて何かが欠けていない限り、サイズだけでなくサイズ*サイズをmallocするのは非常に直感的ではないようです。
  • スループットの測定についての私の理解では、配列サイズに反復回数を掛けてから、かかった時間で割ります。これが正しいという確証を得ることはできますか?

これらは、この課題を理解する上での唯一のハードルです。どんな助けでも大歓迎です。

4

1 に答える 1

2
  • 使用方法の目的は何ですか?

使用法関数は、コマンドラインでプログラムに渡されるはずの引数を示します。

  • 私が知る限り、常に使用法()につながり、sscanf行でパラメーターを取らないので、パラメーターを渡す部分は何をしているはずですか?

無効な引数がプログラムに渡されると、usage() 関数が呼び出されます。

それ以外の場合、変数の反復回数Nを引数の値no_iterations(デフォルト値 100) に設定し、変数の配列のサイズをsize引数の値array_size(デフォルト値 1024) に設定します。

  • この割り当てでは、配列サイズを KB または MB で記録することを意図しています。また、malloc がサイズをバイト単位で割り当て、サイズ変数値が 1024 の場合、1MB * sizeof(int) になることがわかっています (少なくとも)。この場合、記録する必要がある配列サイズは 1MB または 1MB * sizeof(int) でしょうか?

サイズが 1 MB であると想定されている場合、おそらくそれが本来あるべきサイズです。

サイズがデータ型のサイズの係数であることを確認したい場合は、次のようにします。

if (size % sizeof(int) != 0)
{
    size = ((int)(size / sizeof(int))) * sizeof(int);
}
  • パラメータの受け渡しが適切に機能し、パラメータを渡してサイズ変数の値を変更した場合、配列のサイズは常にサイズ変数の 2 乗になりますか? それとも、配列サイズは単なるサイズ変数と見なされますか? これらすべてについて何かが欠けていない限り、サイズだけでなくサイズ*サイズをmallocするのは非常に直感的ではないようです。

sizeおそらく、バイトを割り当てたいだけです。配列だけでなく、行列を扱うことになっている場合を除きます。その場合、それはsize * sizeバイトになります。

  • スループットの測定についての私の理解では、配列サイズに反復回数を掛けてから、かかった時間で割ればよいということです。これが正しいという確証を得ることはできますか?

たぶんそうだ。

于 2012-10-10T02:10:05.267 に答える