コンパイラの最適化について

[戻る]
diolab 2008/07/20(日) 21:00:13
XP pro VS2005

コンパイラについて質問があります.

例えば、

CL1.Cl2.Cl3.Cl4.m_Intger

みたいなクラスのサブクラスのまた奥のふかーいところにある
変数を呼び出すのは時間コストが少しかかると思います.

それを、100万回ループとかのなかで呼び出すと、
無視できなくなってきますよね?

でも、コンパイラが最適化するので大丈夫ということも勉強しました.
でも、その場合の最適化ってどういう風に扱われるかが分かりません.

つまり、
for( i=0; i<1000000; i++){
 myFunc0(CL1.Cl2.Cl3.Cl4.m_Intger);
 myFunc1(CL1.Cl2.Cl3.Cl4.m_Intger);
 myFunc2(CL1.Cl2.Cl3.Cl4.m_Intger);
 ・・・・
 myFunc3(CL1.Cl2.Cl3.Cl4.m_Intger);
}
見たいな場合、

int* num = new int;
*num = CL1.Cl2.Cl3.Cl4.m_Intger;
for( i=0; i<1000000; i++){
 myFunc0(*num);
 myFunc1(*num);
 myFunc2(*num);
 ・・・・
 myFunc3(*num);
}
となるのか、

for( i=0; i<1000000; i++){
 int num = CL1.Cl2.Cl3.Cl4.m_Intger;
 myFunc0(num);
 myFunc1(num);
 myFunc2(num);
 ・・・・
 myFunc3(num);
}

と言うことです.

マルチスレッド化したときとかに、
ループ中に値が変更されたりするのですか?

最適化のルールとかってあるのでしょうか?

御教示お願いいたします、。

επιστημη [HomePage] 2008/07/20(日) 22:04:52
> サブクラスのまた奥のふかーいところにある
> 変数を呼び出すのは時間コストが少しかかると思います.

なぜ? ポインタの連鎖になってるわけじゃないよ?

... 2008/07/20(日) 22:51:21
アセンブラレベルで確認すれば?

diolab 2008/07/21(月) 10:45:19
>επιστημη

そうですか。
ということはコンパイル時に参照したい変数のアドレス?を
直接見にいくようにしてるってことかと思います.

的外れなようなのでもうちょこっと勉強してから聴き直します.
ありがとうございました

wclrp ( 'o') 2008/07/21(月) 12:02:26
どう最適化するかはコンパイラを作る人たちの成果だからな。
コンパイラによるけど最適化オプションが指定できるし。

俺は、デフォルトの最適化に任せているので、
最適化しすぎて困る経験はあまりないけど。
myFunc0を呼び出すとCl3の値が変わるかもしれないことを懸念すると
そこまで最適化するのは逆に迷惑だな。
myFunc0がインライン展開されるとか除いて。

CL1.Cl2.Cl3.Cl4.m_Intgerは、
コンパイル時に*(CL1のアドレス + 24)みたいなものになるよ。

CL1->Cl2->Cl3->Cl4->m_Intgerは、手間がかかるかもね。

>マルチスレッド化したときとかに、
>ループ中に値が変更されたりするのですか?
最適化に関係なく変えれば変わるけど?
num = CL1.Cl2.Cl3.Cl4.m_Intger;
for( i=0; i<1000000; i++){
こういう最適化されればmyFunc0は古い値を使うことになってしまうけど。

たいちう 2008/07/21(月) 20:31:27
> 最適化のルールとかってあるのでしょうか?

質問の意図は、コンパイラの最適化のルールを知って、
効果的な最適化をしたいということ?

普段はそんなこと気にしないでいいじゃね?
ボトルネックになったときにアセンブラを見れば十分過ぎる位だと思う。
その時も実測が優先。

どうしても知りたいというなら、GCCのソースコードを見るとか、開発資料を見るとか、
(迷惑にならないと確信できたら)開発者のコミュニティに質問してみるとか。
いや、開発資料を自力で探して読めないレベルの人の質問は全て迷惑かな。

これで分かるのは、GCCの最適化のルールについてであり、VC++等の市販のコンパイラの
最適化は、その細部については公開されていないはず。その部分がGCCよりも優れていて、
お金をとっている部分ですね。建前としては。

まぁ、GCCの最適化のルールが理解できたら、私や今のdiolabさんには見えないものが
見つかっているでしょうから、先を探してください。

かもねぎ 2008/07/22(火) 02:22:04
http://ja.wikipedia.org/wiki/%E3%82%B3%E3%83%B3%E3%83%91%E3%82%A4%E3%83%A9%E6%9C%80%E9%81%A9%E5%8C%96

まずはこの辺からでしょうか・

仲澤@失業者 2008/07/22(火) 16:47:06
質問は以下の2つなのでしょうか。

>マルチスレッド化したときとかに、
>ループ中に値が変更されたりするのですか?

どの「値」のことかわかりませんが、ループ自体が無くなる場合も
あるので答えは「はい」かなぁ。

>最適化のルールとかってあるのでしょうか?

しりません。しかし、元のコードの「意図」と異なる動作
となることもあることを考えると、
「元のコードと無関係な動作にはならい」だろう。
程度には信用してます(笑)。

ITO 2008/07/25(金) 21:04:52
> でも、コンパイラが最適化するので大丈夫ということも勉強しました.
> でも、その場合の最適化ってどういう風に扱われるかが分かりません.
Cコンパイラーで競っているテーマのひとつですので詳しくは分からないと思います。

>マルチスレッド化したときとかに、
>ループ中に値が変更されたりするのですか?
最適化に関係なくマルチスレッド化する時に対処しなければいけない問題ですね。

かもねぎ 2008/07/25(金) 21:39:25
デバッグモードでasmファイル出して
リリースモードでasmファイル出して
比較して
意図したところが省略されていなければ良いし
意図したところが省略されていたら
コードを修正。
ZeroMemory なんかは省略されそうなので
SecureZeroMemory が良いそうです。
struct HOGE hoge = { 0 } ;
も、省略されそうです・・
セキュアープログラミングとかで
検索するといろいろ出てきます
最適化技術も日々進歩してますからねぇ・・

bun 2008/07/28(月) 18:00:24
今さらなんですが...

これって、最適化に関係あるんでしょうか。
たぶんですが、デバッグ版最適化無しでビルドしたとしても、
  CL1.Cl2.Cl3.Cl4.m_Intger
って、
m_Intgerの先頭アドレスに変換されるだけのような?

myFunc0()とかの関数の引数になってるので、
先頭アドレスがスタックに積まれて終わり。

自信はないのですが、皆さん、難しく考えすぎのような気がしてなりません。

ITO 2008/07/28(月) 22:38:28
>これって、最適化に関係あるんでしょうか。
確かに関係ないような気もしますね。

>自信はないのですが、皆さん、難しく考えすぎのような気がしてなりません。
そうですね、

>的外れなようなのでもうちょこっと勉強してから聴き直します.
>ありがとうございました
ここで一旦途切れているように見えます。

アセンブラレベルまでの話でないように思えます。

wclrp ( 'o') 2008/07/29(火) 00:11:39
すでに
>ポインタの連鎖になってるわけじゃないよ?
がその意味の回答かと思ってた。

bun 2008/07/29(火) 09:30:56
漠然とした疑問が晴れた気がします。
真相を追い求めるには情報が足りないので、この辺りにしておきます。

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

古いスレッドには追加発言できません。