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

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

ただいまの
回答率

91.36%

  • C

    2530questions

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

  • C++

    2424questions

    C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

  • Visual Studio

    1211questions

    Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

  • GCC

    92questions

    GCCはGNU Compiler Collectionの略です。LinuxのC言語コンパイラのデファクトスタンダードであり、数多くの他言語やプラットフォームサポートもします。

clock()による計測の違い

解決済

回答 3

投稿 2017/12/07 16:08

  • 評価
  • クリップ 1
  • VIEW 149

strike1217

score 480

visual studio(windows) 6th-skylake Intel CPU 4.0GHz
gcc linux Debian Intel CPU 1.7GHz
どちらも64bitです。

以下のプログラムをテストしました。
最適化は行っていません。

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

int main(){
    clock_t start, end;
    int n;
    int d;

    start = clock();

    //scanf("%d", &d);

    for(long i = 0; i < 999999999; i++){
        n = i;
    }

    end = clock();
    printf("%f\n", (double)(end - start) / CLOCKS_PER_SEC);

    return 0;
}

gcc : 2.360730
visual studio : 1.624000

となりました。
CPU性能に差があるので、まぁこんなものかなって感じですね。

ところが、scanf()のコメントを外して実行してみると、、、
10秒後くらい経過したら適当にキーを打ちます。
gcc : 2.286145
visual studio : 12.181000

という結果になりまいした。
これって、Linuxの方はscanf()が計測時間に含まれていない・・・ということですよね??

同じソースをvisual studioとgccでコンパイルすると結果に差が出てきてしまいますよね。(例えばゲームとか・・・)

なぜこのような違いがでてくるんでしょうか?
これをscanf()の待ち時間も計測に含める方法ってあるんでしょうか?

わかる方お願いします。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

+3

clockは消費したCPU時間を計ります。
経過時間を計りたければ gettimeofday(古いので非推奨)とかtime(これは秒単位でしか取れない)とか、clock_gettimeをREALTIME指定で使うとかでしょうか。

投稿 2017/12/07 16:19

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/12/07 16:20

    time()は精度が低下してしまうんですよね。
    clock_gettimeは調べてみますね。

    キャンセル

+3

C++11からまともな時間系ライブラリが追加されました。<chrono>ヘッダにあります。

そのうちstd::chrono::high_resolution_clock::now()関数がご希望にそうと思います。

例:
https://github.com/yumetodo/string_split/blob/master/benchmark/benchmark.cpp#L123-L128

計測用の関数に経過時間を図りたい処理を書いた関数へのポインタを渡してあげないと最適化で計測するものが変わってしまうことが極稀にあります。

投稿 2017/12/07 16:22

編集 2017/12/07 17:16

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/12/07 16:23

    「まともな」笑

    それまでの関数は「まとも」ではないということですね!笑

    キャンセル

  • 2017/12/07 16:24

    C言語の方にはないんですかね?
    まともな関数は・・・

    キャンセル

  • 2017/12/07 16:27

    標準ではうーん・・・。

    あと最適化を行わない時間計測は無意味なのでやめましょう。得られる結果がなんの意味も信頼性も持たない。

    キャンセル

  • 2017/12/07 16:29

    そうなんですか!
    わかりました。

    キャンセル

checkベストアンサー

+2

clock()をつかってgccとvisualstudioで計測値に差が出てるのは言語の違いではなくてLinuxとWindowsの違いだと思いますよ。
Linuxはscanfの入力待ちでは一切CPUは使いません。
キー入力と入力しつつある文字の表示とかの処理はGUIシステム側のCPU消費とか、OSの割り込み処理のCPU消費としてカウントされてると思います。

Windowsはscanfを呼び出したプログラム自身が結構CPUを使っちゃってるようですね。

追記:
間違いでした。

Linux glibc 2.18 以降のclockはは、 精度を向上させるため、 clock_gettime(2) (の CLOCK_PROCESS_CPUTIME_ID クロック) を使って実装されていいます。以前はtimes()を使ってましたがどっちにしても消費したCPU時間をはかっています。

一方Winowsのclockはwall-clock timeを返す関数(時刻がわかるので差し引きすると経過時間が出る)で「ISO Cと互換性がない」と書かれています。
https://msdn.microsoft.com/en-us/library/4e2ess30.aspx

そもそも違うものを計っていたと言うことです。

おそらくは、Win321piのGetProcessTimesを使うとかするぼが正解。
C++プログラミングがしたいのならすでに他の方が答えているstd::chrono::high_resolution_clock::now()関数が正解なのでしょう。

投稿 2017/12/07 16:35

編集 2017/12/07 16:57

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/12/07 16:39

    なるほど!
    Linux とWindowsの割り込みの仕組みに違いがあるからということですね。

    キャンセル

  • 2017/12/07 16:42

    windowsはブラックボックスでソースコードの確認ができないので、確認のしようがありませんね〜〜

    ふむーーー。

    キャンセル

  • 2017/12/07 17:11

    さすがにこのレベルでMSDNのドキュメントに嘘は書いてないと思います

    キャンセル

  • 2017/12/07 17:44

    C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\crt\src\clock.c
    C:\Program Files (x86)\Windows Kits\10\Source\10.0.16299.0\ucrt\time\clock.cpp
    どっちかにあるんじゃないかな

    キャンセル

  • 2017/12/07 18:36 編集

    windows clock と linux clockは別物ということですね。

    キャンセル

  • 2017/12/07 18:39

    あ、正確にはvisual studio のclockとgccのclockは別物ということですね

    キャンセル

  • 2017/12/07 18:43

    clock 関数よりも、clock_gettime関数を使用するほうが良さそうですね!!

    キャンセル

  • 2017/12/07 19:51

    clock_gettime関数
    これってwindowsだと使えないんですかね???

    キャンセル

  • 2017/12/07 20:01

    Win32APIというならQueryPerformanceCounter使うのが正確だと記憶しているんですが・・・

    キャンセル

  • 2017/12/07 20:01

    QueryPerformanceCounterはstd::chrono::high_resolution_clock::now()の実装にも使われることがあるので・・・

    キャンセル

  • 2017/12/07 20:03

    win32 APIを使うと移植性がなくなってしまいますぅ

    キャンセル

  • 2017/12/07 20:10

    移植性を求めるならstd::chrono::high_resolution_clock::now()一択

    キャンセル

  • 2017/12/07 20:10

    てっきりここまでの流れは環境依存でもいいやというたぐいの話かと思っていた

    キャンセル

  • 2017/12/07 20:16

    C言語の時間系の関数使えませんね・・・・><

    キャンセル

  • 2017/12/07 20:33

    'CLOCK_REALTIME': undeclared identifier と言われてしまったので、windowsでは使えないようですね。
    C言語の時間系関数は使わずに ,
    C++ の時間系を使った方が良いみたいですね。

    キャンセル

  • 2017/12/07 21:59

    https://www.mm2d.net/main/prog/c/time-03.html

    windowsでも使えるC言語関数なら、timespec_get()というものがあるようですね。

    キャンセル

  • 2017/12/07 22:26

    移植性があり

    C++ 11 : std::chrono::high_resolution_clock::now()
    C11 : timespec_get()

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

    キャンセル

  • 2017/12/07 22:26

    linuxのclockはgccではなくglibc(GNU Cライブラリ)にあります。

    キャンセル

  • 2017/12/07 22:28

    あ、そうですね。すいません。

    キャンセル

  • 2017/12/07 22:31

    Visual C++が CのISO規格と違うclockを提供してるのはなぜなんですかねぇ。。。??その気になれば同じ仕様のclock()も提供可能なはずなんですが。

    キャンセル

  • 2017/12/07 22:39

    う〜〜ん。
    それは確かに疑問ですね。

    同じソースが使えないというのは不便でならないですね。

    キャンセル

  • 2017/12/08 12:43

    標準に準拠しない処理系も含めて移植性を確保するのは不可能なので、ISO C準拠の処理系限定で移植性のあるコードを書くか、機種依存ありで書いて#ifdefとかでソースコードは1つにまとめるか。どっちかではないでしょうか。

    キャンセル

  • 2017/12/09 12:48

    ちょっと待ってください。
    逆に、visual studio でscanf()を計測に含めいないようにするには、どうすれば良いんでしょうかね????

    キャンセル

  • 2017/12/10 08:49

    Win32APIをたたくか、C++標準クラスライブラリに何か使えそうなものがないか探すんでしょうね。

    キャンセル

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

ただいまの回答率

91.36%

関連した質問

同じタグがついた質問を見る

  • C

    2530questions

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

  • C++

    2424questions

    C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

  • Visual Studio

    1211questions

    Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

  • GCC

    92questions

    GCCはGNU Compiler Collectionの略です。LinuxのC言語コンパイラのデファクトスタンダードであり、数多くの他言語やプラットフォームサポートもします。