0

他の操作を推定してプロファイリングするために clock_gettime() 関数の時間を計る必要があります。これは宿題のためなので、プロファイラーを使用できず、独自のコードを作成する必要があります。

私がやっている方法は以下のようなものです:

clock_gettime(CLOCK_PROCESS_CPUTIME_ID,&begin);

for(int i=0;i<=n;i++)
    clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end);
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end);

cout<<(end.tv_nsec-begin.tv_nsec)/n; //time per clock_gettime()

問題は、n=100 の場合、出力: 370.63 ns、n=100000 の場合、出力: 330 ns、n=1000000 の場合、出力: 260 ns、n=10000000、出力: 55 ns、....減少し続けることです。 .

これは命令キャッシュが原因であることは理解していますが、プロファイリングでこれを処理する方法がわかりません。たとえば、gettime を使用して関数呼び出しの時間を見積もる場合、gettime がそれ自体に費やした時間をどのように知るのでしょうか?

これらすべての値の加重平均を取ることは良い考えでしょうか? (必要な操作を同じ回数実行し、その加重平均を取り、gettime の加重平均を差し引いて、キャッシュに関係なく操作の適切な見積もりを取得できますか?)

どんな提案でも大歓迎です。

前もって感謝します。

4

1 に答える 1

0

時差を計算すると、次のようになります。(end.tv_nsec-begin.tv_nsec)/n

経過時間のナノ秒部分のみを考慮しています。tv_nsecフィールドは秒の小数部分のみを反映するため、秒も考慮する必要があります。

int64_t end_ns = ((int64_t)end.tv_sec * 1000000000) + end.tv_nsec;
int64_t begin_ns = ((int64_t)begin.tv_sec * 1000000000) + begin.tv_nsec;
int64_t elapsed_ns = end_ns - begin_ns;

実際、現在のコードでは、 のナノ秒部分endがラップアラウンドし、beginのナノ秒部分よりも小さい場合に、負の結果が得られることがあります。

これを修正すると、より一貫した結果を観察できるようになります。


編集:完全を期すために、テストに使用したコードを次に示します。これにより、非常に一貫した結果が得られます(使用する反復回数に関係なく、呼び出しごとに280〜300ns):

int main() {
  const int loops = 100000000;

  struct timespec begin;
  struct timespec end;
  clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &begin);

  for(int i = 0; i < loops; i++)
      clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end);
  clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end);

  int64_t end_ns = ((int64_t)end.tv_sec * 1000000000) + end.tv_nsec;
  int64_t begin_ns = ((int64_t)begin.tv_sec * 1000000000) + begin.tv_nsec;
  int64_t elapsed_ns = end_ns - begin_ns;
  int64_t ns_per_call = elapsed_ns / loops;
  std::cout << ns_per_call << std::endl;
}
于 2013-10-19T18:13:00.520 に答える