こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

整数演算と実数演算の速度が違いのプログラム

こんにちは、C言語を独学しているものです。
すみませんがお助け頂けますでしょうか?

整数演算と実数演算の速度が違うという練習問題を
テキストから全く同じものを作り、コンパイラしたところです。

#include <stdio.h>
#include <time.h>
#define LOOP 200000L/*ループ回数*/

void main(void)
{
time_t i1,i2,r1,r2; /*Stored for time*/
long l; /*loop counter*/
int idata;
double ddata;

i1=time(NULL); /*Store the time of starting the integ culculation*/
for(l=0L;l < LOOP;l++)
{
idata += 10;
}
i2=time(NULL); /*store the time of ending the integ cal*/

r1=time(NULL); /*Store the time of starting the double cal.*/
for(l=0L;l < LOOP;l++)
{
ddata += 10.0;
}
r2=time(NULL); /*store the time of ending the double cal*/

/* display the stored the time in above by transferred to local time + how long it takes.*/

printf("integer start : %s",ctime(&i1));
printf("integer end: %s",ctime(&i2));
printf("interger process time total : %f(sec)\n",difftime(i2,i1));
printf("Real start : %s",ctime(&r1));
printf("Real end: %s",ctime(&r2));
printf("Real process time total : %f(sec)\n",difftime(r2,r1));
}



コンパイラ中に出たWarning

C:\Practice>bcc32 831.cpp
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
831.cpp:
Warning W8004 831.cpp 15: 'idata' is assigned a value that is never used in func
tion main()
Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland



実行した結果
C:\Practice>831
integer start : Fri Aug 31 15:00:56 2012
integer end: Fri Aug 31 15:00:56 2012
interger process time total : 0.000000(sec)
Real start : Fri Aug 31 15:00:56 2012
Real end: Fri Aug 31 15:00:56 2012
Real process time total : 0.000000(sec)


両方ともStart timeの結果しかできていない、LOOPがうまく動いていないような気がします。
何度Programを見てもどこを直してよいのか分からないので どなたか教えて頂けないでしょうか?
(こんな簡単なこともわからずにお恥ずかしいです、、、。周りに教えてくれる先生がいないのでよろしくお願いします。)

投稿日時 - 2012-08-31 15:08:09

QNo.7673359

困ってます

質問者が選んだベストアンサー

startとendの差が0なのでそのように判断されたのでしょうか?

CPUが速いので200000回の計算はあっという間に終わってしまうのでしょう。
2000000000回にすれば差がでると思いますが…。

それでもだめなら二重ループにして回数を増やすとか…。

でもこの手のテストは最適化の問題だとか、コンパイラのデバグルーティンの挿入だとかの問題が隠されているように思いますから、最初のうちは簡単に確認したら次に進んだ方がいいかも。

投稿日時 - 2012-08-31 15:53:00

お礼

hashioogi先生、
どうもありがとうございました。
Loopを言われた回数に直しました。
とても時間がかかり、心配になりましたが無事に違いがでました。
ありがとうございました。!!
ゆみころ★

C:\Practice>831
integer start : Fri Aug 31 16:08:57 2012
integer end: Fri Aug 31 16:08:59 2012
interger process time total : 2.000000(sec
Real start : Fri Aug 31 16:08:59 2012
Real end: Fri Aug 31 16:13:26 2012
Real process time total : 267.000000(sec)

投稿日時 - 2012-08-31 16:20:46

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(5)

ANo.5

プログラムの性能を計測するのは結構むずかしんです。
特に最近のコンパイラは賢くて最適化がうまく働くと思いがけない性能になってしまうことがあります。

多分、ポイントは以下の警告です。
Warning W8004 831.cpp 15: 'idata' is assigned a value that is never used in func
tion main()
意味は
「idata は値がわりあてられていますが、main関数で使われていません。」
つまりコンパイラは idata の値を使っていないことを認識しているんです。
・値を使っていないんだから代入は意味がない!
・従ってループの中は無処理と同様だ!
・従ってループを処理する必要はない!
とコンパイラは判断することができる訳です。
このような理由で最適化が働いていると、ループ処理の実行時間が0になってしまうことがあります。
ddataについても同様です。

これを防ぐにはコンパイルオプションを操作して最適化を禁止することが必要でしょう。
Borlandのコンパイルオプションのついてはよくわからないので、あしからず。

投稿日時 - 2012-08-31 16:07:24

お礼

maru_yoshi先生
ご解説どうもありがとうございました。
はい、No 4の先生も同じことをご指摘下さいました。
最適化難しいですね、私のコンパイラではできないのかもしれません。
(No4の先生のとおりにやりましたができませんでした)

でも教えて下さりありがとうございました。

ゆみころ★

投稿日時 - 2012-08-31 16:32:22

ANo.4

No.2 訂正です。

> bcc32 -Gd 831.cpp

は、

bcc32 -Od 831.cpp

の間違いです(- のあとは、アルファベットのオー)

投稿日時 - 2012-08-31 15:58:44

お礼

Asano Nagi先生
詳しいご説明どうもありがとうございました。

最適化、、、まだまだそのレベルまで達していないので
未知の世界でした。
残念ながら最適化とVolitileは働きませんでした。


C:\Practice>bcc32 -Od 831.cpp
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
831.cpp:
Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland

C:\Practice>831
integer start : Fri Aug 31 16:22:45 2012
integer end: Fri Aug 31 16:22:45 2012
interger process time total : 0.000000(sec)
Real start : Fri Aug 31 16:22:45 2012
Real end: Fri Aug 31 16:22:45 2012
Real process time total : 0.000000(sec)

ですが勉強になりました。ありがとうございました。

ゆみころ★

投稿日時 - 2012-08-31 16:26:22

ANo.3

ループ回数が足りないので20億回くらい回してください。
或いは時間を求めるのにclock()関数を使ってください。

投稿日時 - 2012-08-31 15:58:31

お礼

honor先生、

アドバイスどうもありがとうございました。
Loop数を増やしたら無事に結果がでました。
clock()関数はまだわからないので、できるようになったらまた作っています。
(テキストをはじめから読んでいるため、現在のPageの内容までしかわかりません。ごめんなさい。)

ゆみころ★

投稿日時 - 2012-08-31 16:28:53

ANo.2

もしかしたら、

bcc32 -Gd 831.cpp

でコンパイルすると、それなりの結果になるかもしれません。
あるいは、

volatile int idata;
volatile double ddata;

にしてみるとか。

さて、これは、「最適化」という機能が影響しています。
もともと、プログラムというのは、同じ動作ならなるたけ早く動いて欲しいというのが一般的です。

そこで、最近のコンパイラは、

for(l=0L;l < LOOP;l++)
{
idata += 10;
}

こんなコードを見ると、あっさりと、

idata += 10 * LOOP; (実際には、10 * LOOP も事前に計算して)

と置き換えます。

あるいは、

Warning W8004 831.cpp 15: 'idata' is assigned a value that is never used in function main()

という警告が出ていますが、これは、「idata には値がセットされているが、その後使われていない」という意味です。

コンパイラは、(どうせセットしても使わないのだから)idata への代入すら省略する可能性もあります。

というわけで、

-Gd というオプションは、「最適化禁止」を意味しますし、
volatile という指定は、「この変数は書かれたとおりに処理するように」というような意味合いになります。

投稿日時 - 2012-08-31 15:54:20

お礼

No 4のほうにコメントを残させて頂きました。
ゆみころ★

投稿日時 - 2012-08-31 16:26:58

あなたにオススメの質問