1

私はC言語でtime.hライブラリを使って楽しんでいました。いくつかの基本的な関数のクロック ティック数を測定して、実際の速度を把握しようとしていました。私はclock() 関数を使用しました。この場合、printf()関数を測定していました。

私のプログラムを見てください:

#include <stdio.h>
#include <time.h>

void main()
{
    const int LIMIT = 2000;
    const int LOOP = 20;
    int results[LOOP];

    for(int i=0; i<LOOP; i++)
    {
        int j;
        clock_t time01 = clock();

        for(j=1; j<LIMIT; j++)
        {
            printf("a");
        }

        clock_t time02 = clock();
        results[i] = (int) (time02 - time01);
    }

    for(int i=0; i<LOOP; i++)
    {
        printf("\nCLOCK TIME: %d.", results[i]);        
    }
    getchar();
}

このプログラムは基本的に、printf("a") 関数と呼ばれる 2000 回のクロック ティック数の 20 回をカウントするだけです。

私が理解していない奇妙なことは結果です。ほとんどの場合、他のテストを行っている場合でも、ランダムに2 つのグループの結果が得られます。

CLOCK TIME: 31.
CLOCK TIME: 47.
CLOCK TIME: 47.
CLOCK TIME: 31.
CLOCK TIME: 47.
CLOCK TIME: 31.
CLOCK TIME: 47.
CLOCK TIME: 31.
CLOCK TIME: 47.
CLOCK TIME: 47.
CLOCK TIME: 31.
CLOCK TIME: 47.
CLOCK TIME: 31.
CLOCK TIME: 47.
CLOCK TIME: 47.
CLOCK TIME: 31.
CLOCK TIME: 47.
CLOCK TIME: 31.
CLOCK TIME: 47.
CLOCK TIME: 31.

コンパイラがその関数をどのように正確に処理するかわかりません。私が推測する文字のテストがありますが、それはその違いにはなりません。コンパイラがメモリ内で何かを行っているように見えます... (?) このコードをコンパイルする正確な背景や、上記の違いが現れる理由を知っている人はいますか? または、少なくとも私に役立つリンクはありますか?

ありがとうございました。

4

3 に答える 3

2

少なくとも 2 つの原因が考えられます。

  1. 時計の解像度には制限があります。
  2. printf時々バッファをフラッシュします。
于 2012-02-25T16:01:00.363 に答える
1

一部のコンパイラ(特に最近のgccLinux ディストリビューションの の最近のバージョンで、 を使用し-O2て最適化する場合) は、printf("a")putchar()

writeしかし、ほとんどの時間はシステム コールを実行するカーネルで費やされます。

于 2012-02-25T16:04:19.333 に答える
-1

のmanページclockは、

プログラムが使用するプロセッサ時間の概算

この概算は、有名なTime Stamp Counterに基づいています。ウィキペディアが言うように:

リセットからのサイクル数をカウントします

残念ながら、最近では、このカウンターはコアごとに異なる場合があります。

1 つのマザーボード上の複数の CPU のタイムスタンプ カウンターが同期されるという保証はありません。

そのため、コードを特定の CPU にロックするように注意してください。そうしないと、引き続き奇妙な結果が得られます。また、正確な結果を検索しているように見えるので、clockcallの代わりに次のコードを使用できます。

  uint64_t rdtsc(void) {
    uint32_t lo, hi;
    __asm__ __volatile__ (      // serialize
    "xorl %%eax,%%eax \n        cpuid"
    ::: "%rax", "%rbx", "%rcx", "%rdx");
    /* We cannot use "=A", since this would use %rax on x86_64 and return only the lower 32bits of the TSC */
    __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
    return (uint64_t)hi << 32 | lo;
  }
于 2012-02-25T17:35:03.163 に答える