C言語関係掲示板

過去ログ

No.1065 マイクロ秒まで時間計測

[戻る] [ホームページ]
No.13933

#include <sys/types.h>について
投稿者---カイト(2004/05/11 15:51:47)


ユニックスのCでプログラムを作成しています。
ユニックス環境では時間計測に#include <sys/types.h>を用いてマイクロ秒まで計ることができましたが、ウインドウズではなぜか'sys/time.h': No such file or directoryというエラーが出てしまします。
どうすれば計ることができるのでしょうか??
教えてください!!



No.13937

Re:#include <sys/types.h>について
投稿者---RiSK(2004/05/11 16:06:09)


>どうすれば計ることができるのでしょうか??
>教えてください!!

Google 検索: c 時間計測で一番上が参考になるかもしれません。


No.13938

Re:#include <sys/types.h>について
投稿者---カイト(2004/05/11 16:38:21)


さっそくありがとうございます!!
Visual C++ バージョン (オーバーヘッドをとにかく少なくしたい場合) を実行してみましたがこれもエラーでできません。
なるべくオーバーヘッドが出ないようにしたいので。
ウインドウズではマイクロ秒まで計ることは出来ないのでしょうか??


No.13939

Re:#include <sys/types.h>について
投稿者---RiSK(2004/05/11 17:02:13)


> Visual C++ バージョン (オーバーヘッドをとにかく少なくしたい場合) を
> 実行してみましたがこれもエラーでできません。
そのエラーを書くのがマナーです。

> なるべくオーバーヘッドが出ないようにしたいので。
これは インラインアセンブラの領域です。
# C とは直接関係ありません。

>ウインドウズではマイクロ秒まで計ることは出来ないのでしょうか??
出来るのでは?

とりあえずサンプルの先頭に
#include <windows.h>
#include <stdio.h>
をぶち込めばエラーは消えるはずです。

念のためですが、インラインアセンブラに関する質問には
私は答えられません。 (^^;;


No.13940

VCによる時間計測 正確なリンク先 (was: Re:#include <sys/types.h>について)
投稿者---RiSK(2004/05/11 17:11:50)


Google 検索: c 時間計測で一番上が参考になるかもしれません。
将来変わると思うのでそのリンクをはっきりさせます。
Cによる時間計測です。



No.13941

Re:VCによる時間計測 正確なリンク先 (was: Re:#include <sys/types.h>について)
投稿者---カイト(2004/05/11 17:20:06)


丁寧にありがとうございます!!
エラーは、
LARGE_INTEGER' : 定義されていない識別子です
構文エラー : ';' が、識別子 'tsc' の前に必要です。
'LowPart' : 'オペランド 1' に不正な構造体または共用体のメンバがあります
'.QuadPart' : 左側がクラス、構造体、共用体ではありません
などが出るのですが正直全然わかりません。

さきほどのHPからコピーして計りたい所にペーストしているので間違いはないと思うのですがエラーが出てしまいます。
今からまた調べるので何かわかったらよろしくお願いいたします。


No.13946

Re:VCによる時間計測 正確なリンク先 (was: Re:#include <sys/types.h>について)
投稿者---RiSK(2004/05/11 18:09:54)


>エラーは、
> (snip)
>などが出るのですが正直全然わかりません。
どうもです。

>さきほどのHPからコピーして計りたい所にペーストしているので
>間違いはないと思うのですがエラーが出てしまいます。
>今からまた調べるので何かわかったらよろしくお願いいたします。
一点、分かりました。
No.13939,RiSK(2004/05/11 17:02:13)を最後まで読めば解決できると思います。


No.13947

Re:#include <sys/types.h>について
投稿者---nop(2004/05/11 18:23:28)


>マイクロ秒まで(中略)どうすれば計ることができるのでしょうか??

その機械の1クロックがマイクロ秒以上の時は計れない、
(※つまりは環境依存)と言う事はご承知の上ですか?


【掲示板ご利用上の注意】より
>・なるべく詳しく環境などの情報をお書きください。


No.13950

Re:#include <sys/types.h>について
投稿者---たか(2004/05/11 19:13:08)


SetPriorityClass();
QueryPerformanceFrequency();
QueryPerformanceCounter();

この3つを組み合わせればWindowsでかなり高精度な測定ができます。
但しマルチタスキング環境ですのであくまでも参考に。


No.13951

Re:#include <sys/types.h>について
投稿者---カイト(2004/05/11 19:28:22)


RiSKさんへ

#include <windows.h>、#include <stdio.h>を実行してみましたが、やはり出来ませんでした↓
#include<sys/time.h>が存在しないみたいです。


nopさんへ

環境はWINDOWS2000、Visual C++、メモリ512M、CPUはペンティアム4の2.4Gです。
>その機械の1クロックがマイクロ秒以上の時は計れない、
(※つまりは環境依存)と言う事はご承知の上ですか?
クロック数はどうやって調べればいいのでしょうか??
初心者なのですいません。


たかさんへ

SetPriorityClass();
QueryPerformanceFrequency();
QueryPerformanceCounter();
この3つについては知りませんでした!
今から調べて勉強してきます。



No.13956

Re:#include <sys/types.h>について
投稿者---RAPT(2004/05/11 21:39:56)


VC++って、4? 5? 6? 7? バージョンもきちんと書きましょう。

とりあえず、VC++6として話を進めます。

LARGE_INTEGERはσ(^^)の環境では、PlatformSDK内のWinNT.hにありました。
#include <windows.h>
#include <WinNT.h>
とすれば使えます。


> さきほどのHPからコピーして
どの部分を?

> 計りたい所にペーストしているので間違いはないと思うのですが
環境依存です。

> 環境はWINDOWS2000、Visual C++、メモリ512M、CPUはペンティアム4の2.4Gです。
> (snip)
> クロック数はどうやって調べればいいのでしょうか??

2.4GHz って、自分で言っているじゃありませんか。
CPUのクロック周波数をxxMHzやxxGHzといいますが、Hzは1秒あたりの波の数です。
よって、このCPUは1秒間に24億クロック持ち、1クロックあたり24億分の1秒必要とします。
# アセンブラ+RISC/CISC関係をやっている人は常識かな?
で、1μ秒は100万分の1秒ですから、あとは自分で計算しましょう。

> #include <windows.h>、#include <stdio.h>を実行してみましたが、やはり出来ませんでした↓
> #include<sys/time.h>が存在しないみたいです。
当方の環境には、sys/time.h は存在していません。

中途半端なことをしないで、あなたのコードのうち、状態を再現できる
最小のコードを提示したほうが早いかと思われます。



No.13957

Re:#include <sys/types.h>について
投稿者---たか(2004/05/11 22:52:51)


以下拾い物のソースで、しかもC++ですが、Cには簡単に直せると思いま
す。SetPriorityClassをREALTIME_PRIORITY_CLASSにするとより精密に
測定できますが、プログラムが永久ループに飛び込んだ場合Ctrl+Cも
まともに効かなくなりますので、必ず正常終了する関数のみ
REALTIME_PRIORITY_CLASSにして下さい。

#include <iostream>
#include <windows.h>
#include <iomanip>

struct Time {
  __int64 counter;
  __int64 frequency;
};

Time prof(void (*func)());
void test();

int main()
{
  Time t;

  t = prof(test);

  std::cout << "Counter = " << t.counter << std::endl;
  std::cout << "Frequency = " << t.frequency << std::endl;

  std::cout << std::setprecision(16) << (double)t.counter / t.frequency << " sec." << std::endl;
}

Time prof(void (*func)())
{
  __int64 start, end, freq;
  HANDLE hndl;
  DWORD orgclass;
  Time t;
  
  hndl = GetCurrentProcess();
  orgclass = GetPriorityClass(hndl);

  Sleep(10); 
  SetPriorityClass(hndl, HIGH_PRIORITY_CLASS); // REALTIME_PRIORITY_CLASS
  QueryPerformanceFrequency((LARGE_INTEGER*)&freq);
  QueryPerformanceCounter((LARGE_INTEGER*)&start);

  func();

  QueryPerformanceCounter((LARGE_INTEGER*)&end);
  SetPriorityClass(hndl, orgclass);

  t.counter = end - start;
  t.frequency = freq;
  
  return t;
}

void test() // 時間を計測する関数
{
  for (int i = 0; i < 50000; i++)
    for (int j = 0; j < 100000; j++);
}



No.13958

Re:#include <sys/types.h>について
投稿者---たか(2004/05/11 23:00:01)


もちろんこの結果も 1 / frequency(秒) 未満の結果は無意味ですので
注意しましょう。


No.13961

Re:#include <sys/types.h>について
投稿者---RiSK(2004/05/12 08:44:31)


#include <windows.h>、#include <stdio.h>を実行してみましたが、 やはり出来ませんでした↓
#include<sys/time.h>が存在しないみたいです。

ぉぃぉぃ。私が挙げたリンク先で
#include <sys/time.h> してなかったでしょ。。
すぐに取っ払ってください。

RAPT さんがおっしゃるように Windows+VC6 環境にはありません。
単に #include <time.h> なら通ると思いますが、
Unix 依存の関数はいずれにせよないと思います。

/*
環境:
Windows Me/VC6/PSDK February 2003/SDK/PentiumIII 1GHz/Mem 256MB

参考(ってかほとんどパクリ):
http://www.super-computing.org/sr8000/timer.html
○Visual C++ バージョン (オーバーヘッドをとにかく少なくしたい場合)
*/
#include <windows.h>
#include <stdio.h>

int main(void)
{
  LARGE_INTEGER tsc;

  __asm{
    rdtsc
    mov tsc.LowPart, eax
    mov tsc.HighPart, edx
  }
  /* 計測したいものを入れる */
  __asm {
    rdtsc
    sub eax, tsc.LowPart
    sbb edx, tsc.HighPart   // sub ではなく sbb を使う

    mov tsc.LowPart, eax
    mov tsc.HighPart, edx        
  }
  printf("elapsed tsc=%I64d\n",tsc.QuadPart);

  return 0;
}

実行例:
F:\programing\VC\practice\C言語関係掲示板1\13938\Release>13938
elapsed tsc=33



No.13968

Re:#include <sys/types.h>について
投稿者---カイト(2004/05/12 15:44:24)


みなさん丁寧にありがとうございます!
<sys/time.h>はないことがわかりました。

RiSKさんに教えていただいたプログラムを試した所、実行することができました!
ただ、elapsed tsc=33のように秒数は計れていると思うのですがこの数字が何を示しているのかがわかりませんでしたので、これから調べたいと思います。
ちなみにクイックソートを実行してみたところ、
(データは数値で整数のみ)
データ10→tsc=3500くらい
データ100→tsc=34000くらい
データ1000→tsc=425000くらい
データ10000→tsc=5150000くらい
の数値が出ました。


No.13971

Re:#include <sys/types.h>について
投稿者---カイト(2004/05/12 17:11:04)


調べてみました!
tsc.QuadPartの数値をdouble型のaに代入して、aをクロック数の24億で割ってみました。
clockを使った場合は、
データ10万→0.03秒
データ100万→0.3秒
データ1000万→3.35秒

LARGE_INTEGERの場合は
データ10万→0.025秒
データ100万→0.3秒
データ1000万→3.35秒となりました。

データが100万以上では差はでなかったものの10万だと少し差が見られました。この計算方法であっているのでしょうか??もしわかる方がいたらアドバイスをお願いいたします。


No.14006

Re:#include <sys/types.h>について
投稿者---RiSK(2004/05/13 22:22:47)


>tsc.QuadPartの数値をdouble型のaに代入して、aをクロック数の24億で割ってみました。
>この計算方法であっているのでしょうか??

あっていると思います。
C標準ライブラリ関数に時間差を求める difftime() があります。
制度は非常に低いですが(秒以上)、今回の場合でも確認程度には使えます。

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

#define Hz (1*1000*1000*1000) /* 1GHz (自分の環境により変更) */
#define LOOP 400000000 /* int でオーバーフローしない範囲で変更 */

int main(void)
{
  LARGE_INTEGER tsc;
  double asm; /* インラインアセンブラでの時間 */

  time_t befor, after;
  double cstd; /* C標準ライブラリでの時間 (秒以上) */

  int i;

  time(&befor);
  
  __asm{
    rdtsc
      mov tsc.LowPart, eax
      mov tsc.HighPart, edx
  }
  for (i = 0; i < LOOP; i++); /* ダミーの計算 */
  __asm {
    rdtsc
      sub eax, tsc.LowPart
      sbb edx, tsc.HighPart
      mov tsc.LowPart, eax
      mov tsc.HighPart, edx        
  }
  asm = (double)tsc.QuadPart / Hz;
  time(&after);

  puts("インラインアセンブラの結果:");
  printf("%2.9f(秒) = %I64d(クロック) / %d(Hz)\n\n", asm, tsc.QuadPart, Hz);

  cstd = difftime(after, befor);
  puts("C標準ライブラリの結果:");
  printf("%2.9f(秒) = difftime(after, befor);\n", cstd);

  return 0;
}

関係ない話ですが、タイトルからはだいぶはずれてますね…
ふさわしいと思える場合は、タイトルを適切に変えるか、
新しいスレッドをたてるなど、工夫してくださいね。
# …とはいうもののタイトルを考えるのは難しいですね…


No.14007

Re:#include <sys/types.h>について
投稿者---RiSK(2004/05/13 22:40:44)


訂正。(ToT
制度は非常に低いですが(秒以上)、今回の場合でも確認程度には使えます。
精度は非常に低いですが(秒以上)、今回の場合でも確認程度には使えます。
  time_t befor, after;
  time_t before, after; /* 以下、すべて before に読み替えてください */