質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

3回答

1729閲覧

【C言語】clock()の挙動

退会済みユーザー

退会済みユーザー

総合スコア0

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2022/01/08 03:53

困っていること

clock() / CLOCKS_PER_SECでCPUの経過時間を計測したいのですが、clock()の挙動がうまく把握できません。clock() / CLOCKS_PER_SECでCPU経過時間の秒数を計測できるはずですが、ストップウォッチで測る時間と大きくことなります。

2番目の該当コードの場合はうまくいくのですが一番目の該当コードの場合うまく機能しません。その理由がなんなのかが知りたいです。

該当のソースコード

1

1#include <stdio.h> 2#include <time.h> 3 4int main(void) 5{ 6 int i; 7 clock_t cpu_time; 8 double sec; 9 10 /* 負荷を掛ける処理(適当です) */ 11 for (i = 0; i < 1000000; i++) 12 { 13 printf("\r計測中..."); 14 } 15 16 /* CPU時間をチェック */ 17 cpu_time = clock(); 18 19 /* 秒に直す */ 20 sec = (double)cpu_time / CLOCKS_PER_SEC; 21 22 printf("%f秒\n", sec); 23 24 return 0; 25} 26

2

1#include <stdio.h> 2#include <time.h> 3#include <stdlib.h> 4 5#define MAX_STAGE 10 6 7int sleep(unsigned long x) 8{ 9 clock_t c1 = clock(), c2; 10 11 do 12 { 13 if ((c2 = clock()) == (clock_t)-1) //エラー検出 14 { 15 return 0; 16 } 17 18 } while (1000.0 * (c2 - c1) / CLOCKS_PER_SEC < x); 19 return 1; 20} 21 22int main(void) 23{ 24 sleep(1000); 25 printf("1秒後"); 26 27 return 0; 28} 29

実行結果

1

1//ストップウォッチで計測した場合2~3秒程度でした 2計測中...0.263727秒

2

1//1秒後に表示される 21秒後 3

###OS
MacOS Monterey ver12.1です

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2022/01/08 04:01

「あくまでCPU時間のため、精度がミリ秒まであるとまでは言えませんが、手元のストップウォッチと計測を比べるとほぼ一致していました。」記載されているのですが、10倍違う結果になってしまいます。
dodox86

2022/01/08 09:05

なぜ挙動が違うも何も、提示の1と2は完全に別モノのコードですが、、
guest

回答3

0

その理由がなんなのかが知りたいです。

推測ですが、、printf("\r計測中..."); が I/O(画面出力)待ちとなっているから。
画面出力がそんなに早いとは思えません。CPU時間に I/O待ちが含まれないという事では?

投稿2022/01/08 13:02

pepperleaf

総合スコア6385

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2022/01/08 14:09

なるほど、printf("\r計測中...");のときはCPUは活動していないということでしょうか?
pepperleaf

2022/01/09 02:56

このプログラムとしては、活動してない、、、でしょう。 (当然、OSとかは動いてるので)
guest

0

その理由がなんなのかが知りたいです。

ループの中で printf をしているからでは?

clock()はクロック数と認識しております。

経過時間を返すと勘違いしてますね? man clockを見ましょう

投稿2022/01/08 11:34

sigsegv

総合スコア895

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sigsegv

2022/01/09 02:56 編集

>CPU経過時間 まだそんなことを。そんなページじゃなくmanを読んで
退会済みユーザー

退会済みユーザー

2022/01/09 09:48

うまく言葉にできませんがI/Oに関してはCPU経過時間に含まれないという解釈に行きつきました
guest

0

ベストアンサー

何を計っているのかを正しく知る必要があるものと思います。

【C言語】時間計測に用いる time 関数と clock 関数の違いは?

投稿2022/01/08 04:03

jimbe

総合スコア13209

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2022/01/08 04:07

clock()はクロック数と認識しております。でも一番と二番の挙動が違くなる理由がよくわかりません
jimbe

2022/01/08 04:11

リンク先の記事をよくお読みになった上ですと、何が「よくわからない」のかが分かりません。 例えば記事のどの部分が分からないでしょうか。
jimbe

2022/01/09 04:23 編集

> 秒数計測がなぜうまく機能しない うまく機能しない、のではありません。プログラムはコードの通り動作しています。 うまく機能すればこうなるはず、の「こうなるはず」が間違っているのです。 shuta_202141 さんはプログラムを実行したら「プログラムが終わるまで CPU はこのプログラムの為にずっと動作している」とイメージされているように感じます。 ですが実際はそうではありません。 daeudaeu.com ではその状態を > 例えば CPU が「他のプログラムの処理を行っている」「何もしていない(遊んでいる)」ような時間は CPU 時間として計測されないです。 と表現してイラストまで付けています。 shuta_202141 さんはこの意味をまだ理解されていないのではないでしょうか。 そしてこの「CPU 時間として計測されない」時間は、コンパイラだけでなく、実行する環境 (OS や CPU 性能等 ) で大きく変わります。 daeudaeu.com の記事で最初に > C言語でプログラムの処理時間を計測するとき、何の関数を使って計測していますか? > 僕は clock 関数だね! ミリ秒単位でも計測できるから便利なんだよね > でなるほど。でもその理由だけで clock 関数を使うのは危険だよ? と書かれているのは、clockの返す時間 ( クロック数 ) は「(いわゆる)プログラムの処理時間」では無いからです。
退会済みユーザー

退会済みユーザー

2022/01/09 08:55

まずはご丁寧に回答ありがとうございます。 printf("\r計測中...");のときはCPU時間として計測されていないという認識であってますでしょうか? ですが、該当コード2のsleep関数はsleep(1000)としたときなぜきっちり1秒後に表示されるのでしょうか?
jimbe

2022/01/09 09:07

該当コード2 は sleep で printf していませんが。
退会済みユーザー

退会済みユーザー

2022/01/09 09:49

たしかにそうですね。printfのようなI/Oに関してはCPU計測時間に含まれないという解釈に行きつきました
dodox86

2022/01/09 10:02

@質問者 shuta_202141さん clock()を「計測時間」のように捉えるから誤解が解けないのだと思います。clock()を呼び出しているプログラムが、呼び出した時点までに消費したCPU時間、です。該当コードの2は、自作のsleep関数の中で、引数で指定した時間の間つまりCPU時間を消費するまでdo~while()ループで無理やり回しています。だから1秒経つまでsleep()から出てこない動きになり、結果的に1秒待機しているかたちです。 尚、clock()はUN*Xによって多少実装が異なる場合があるので、その点は留意してください。 macOSのmanpage https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/clock.3.html Linuxのmanpage https://linuxjm.osdn.jp/html/LDP_man-pages/man3/clock.3.html
退会済みユーザー

退会済みユーザー

2022/01/09 12:51

正しくは計測時間ではなく、clock()を呼び出しているプログラムが、呼び出した時点までに消費したCPU時間でその表し方がクロック数であるということですね。それでCLOCKS_PER_SECで割ることで秒数に変換できるということですね。 ようやく理解できました。本当にみなさまありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問