- - PR -
1msの分解能を得る方法について
1|2|3|4
次のページへ»
投稿者 | 投稿内容 | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2005-12-25 16:36
こんにちは。
僕は、コンパイラとしてVisual C++.NETを使用しC言語の練習をしています。 一定時間、待機するプログラムを作成しています。 C言語にSleep関数があり、それを使用しているのですがSleep関数は約10ms待機するのが限界であるということをネットを通して知りました。 自分は、1msの待機時間を得たいと思っているのですが、Windowsプログラミングの関数にはそのような関数はあるのでしょうか?もし、使用方法まで教えていただけたらと思います。 また、常に1msや10msの待機時間を得ることは可能でしょうか?やはり、PC内で走っているプロセスやPCの種類等によって1ms確保することは不可能なのでしょうか? よろしくお願いします。 | ||||||||||||||||
|
投稿日時: 2005-12-25 17:28
どっかで聞いた事ありますね。(ソース忘れました^^;) 因みに言語の限界ではなくて、Windows OS の限界ですね。
リアルタイム OS ではないので、やはり、「おおよそ」 10ms になってしまいます。 起動するプロセスのプライオリティを最大にすれば、期待値に近づくでしょうけど、やはりおおよそでしょうね。 _________________ 囚人のジレンマな日々 | ||||||||||||||||
|
投稿日時: 2005-12-25 17:43
こんばんは。
私もそのような話を聞いたことあります。システムタイマの10ms以下はあてにはならないようです。
どこまで待機時間の誤差が許容範囲か分かりませんが… 「マルチメディアタイマー」 「高分解能カウンター」 を使えば、可能なのではないでしょうか。 一応、 「システムタイマー」「マルチメディアタイマー」「高分解能カウンター」の分解能を調べる テストプログラムを作成してみました。 #正しいのか自信はないのですが(~_~;)
私の使用しているPCでは次のような結果になりました。
| ||||||||||||||||
|
投稿日時: 2005-12-25 17:50
分解能と精度が別な物なのは分かってますよね? 1ms の「精度」のタイマは無理です。 実行されているプロセスや割り込みの量などによって変動してしまいます。 リアルタイムOSではないので、変動の範囲も様々です。 1ms, 10ms の「分解能」のカウンタは、既出の方法で利用可能です。 | ||||||||||||||||
|
投稿日時: 2005-12-25 18:15
返信ありがとうございます。
Windowsの場合10msが限界なのですね・・・。Linuxの場合、およそ1msを得ることができるとネット上に記載されていました。しかし、Linuxをほとんど触ったことがないため、あまりLinuxへと移行する気になれません ^^; そこで、ダミー処理をかますことで、大体1msを得ることができないかと思っています。 ダミー処理は、for文を用いました。 以下に行ったことを示します。 1.別プログラム上で、QueryPerformanceFrequencyとQueryPerformanceCounterを用いて、ダミー処理の実行時間を計測。 [プログラム] #include <stdio.h> #include <windows.h> /*==================================================* * main *==================================================*/ void main(void) { /* LONGLONG, _int64: 64bit integer */ LONGLONG freq, cnt1, cnt2; int r; int y; unsigned long total = 0; r = QueryPerformanceFrequency( (LARGE_INTEGER *)&freq ); if( r != 0 ) { /* %I64d は、64bit integer用 */ printf( "freq=%I64d(Hz)\n", freq ); } else { printf( "Not install High-resoution counter\n" ); } QueryPerformanceCounter( (LARGE_INTEGER *)&cnt1 ); /* 計測したい処理をここに記述する サンプルは何もしないので、QueryPerformanceCounterの オーバーヘッドを計測していることになる */ //上記のコメントは、理解できていないのですが、以下にfor文を記述 しまして、for文の処理時間を計測 for(y=0;y<150000;y++){ total += y; } printf("total:%lu\n",total); QueryPerformanceCounter( (LARGE_INTEGER *)&cnt2 ); /* %I64d は、64bit integer用 */ printf( "cnt1=%I64d\n", cnt1 ); printf( "cnt2=%I64d\n", cnt2 ); printf( "t2-t1=%I64d\n", cnt2 - cnt1 ); printf( "t2-t1=%.1f(usec)\n", (double)(cnt2-cnt1) / freq * 1000000.0 ); } 2.1のプログラムを実行し、だいたい1msとなるループ回数を得て、作成中のプログラムに実装。 あやふやな言い回しかもしれませんが、タイマープログラムを作成しおおよそ1msのダミー処理を作成し、そのダミー処理を作成中のプログラムに実装したということです。 [質問内容] ・タイマープログラムを実行するたびに、処理時間が異なるのは、避けられないのでしょうか?たとえば、1回目が0.5msであったのに対して2回目は1.3msであったりします。 ・ダミー処理をほどこすことは、実際の開発現場などでやられているのでしょうか?それとも、邪道なやり方なのでしょうか? よろしくお願いします。 [参考サイト] http://homepage1.nifty.com/aok2/004/win01.html [ メッセージ編集済み 編集者: ばーど 編集日時 2005-12-25 18:17 ] [ メッセージ編集済み 編集者: ばーど 編集日時 2005-12-25 18:17 ] [ メッセージ編集済み 編集者: ばーど 編集日時 2005-12-25 18:18 ] | ||||||||||||||||
|
投稿日時: 2005-12-25 18:25
囚人さん、Tdnr_Symさん、渋木宏明さん。
書き込みありがとうございます。 [引用文] 分解能と精度が別な物なのは分かってますよね? すみません。分かっていません。 [引用文] 1ms の「精度」のタイマは無理です。 実行されているプロセスや割り込みの量などによって変動してしまいます。 リアルタイムOSではないので、変動の範囲も様々です。 1msの「精度」のタイマを作ることは不可能なのですか・・・ 確かに、変動の範囲が激しいです。 | ||||||||||||||||
|
投稿日時: 2005-12-25 23:20
こんなのとか
http://www.microsoft.com/japan/windows/embedded/partners/product_info/isv/micronet2.asp こんなのは、いかがでしょう? http://www.kuka-controls.com/jp/index.html | ||||||||||||||||
|
投稿日時: 2005-12-26 10:55
原則として避けられません。WindowsはプリエンプティブマルチタスクOSです。動作しているアプリケーションがあなたのプログラムだけではない以上、何時どのような理由で他の処理が割り込むか分かりません。 アプリケーションの実行プライオリティをRealTimeにすれば外乱要因を大幅に排除する事が出来ますが、無くす事は出来ません。Kernelドライバとして実装するなら外乱要因をなくす事も出来ますが、手間がかかりすぎるでしょう。そして何より他のアプリケーション(OSも含めて)の動作を大きく阻害するので、色々と制約の大きなものになるでしょう。
邪道です。他のアプリケーションの処理を大きく阻害し、CPUリソースを無駄に消費するからです。 #ところで・・・ #QueryPerformanceCounterで経過時間を測定してLoopを脱出するように、何故しない? _________________ 甕星 <mikahosi@abox9.so-net.ne.jp> http://blogs.msmvp.jp/mikahosi/ |
1|2|3|4
次のページへ»