ページ 1 / 1
参照とinlineとの違い
Posted: 2012年1月21日(土) 14:10
by QQQ
初歩的な質問で申し訳ありません。
例えば、
int fan1(int &x) {
return x*x*x;
} ;
inline int fan2(int x) {
return x*x*x;
} ;
int a=100;
fan1(a); // 参照渡し。fan1がinline関数ではない
fan2(a); // fan2をinline関数として定義されている場合
fan1(a)とfan2(a)の実効速度はどっちが速いでしょうか。
それとも、fan1(a)とfan2(a)が同じマシンコード生成されるのでしょうか。
宜しくお願いします。
Re: 参照とinlineとの違い
Posted: 2012年1月21日(土) 15:18
by softya(ソフト屋)
実際に試されてはどうでしょうか?
gccとVC++ではマシンコードも違いますし最適化率も違います。前後のコード如何でも最適化の形が変わってきます。
後戻り値をちゃんと使っていないので、それも最適化を妨げる要因になると思います。
最適化レベルは速度最優先を選びましょう。あるいは推奨最適化レベルを選ぶか。
【補足】fan1で気になるのは戻り値である必要があるのかって事ですね。戻り値で戻す分無駄なコードが出るような・・・。
それと検証として参照とint型の値渡しは等価?あるいは参照が不利のような気もするので効果が怪しいです。
Re: 参照とinlineとの違い
Posted: 2012年1月21日(土) 15:25
by YuO
inlineと参照はまったく別の話ですが……。
inlineは,関数の実体を関数の呼び出し箇所に埋め込むよう,処理系にお願いするための物です。
参照は,関数にオブジェクトを参照渡しするための物です。
# ポインタはポインタオブジェクトを値渡ししています。
なので,比較対象として意味が無いのですが……。
速度の問題だけでいうなら,fan2の方が通常は速いと思います。
inlineとは関係なく,xが値渡しであるためです。
# 通常,参照の引数は,実装としてはポインタを渡すことになるため,逆参照の回数が増える。
Re: 参照とinlineとの違い
Posted: 2012年1月21日(土) 15:59
by beatle
一概にどっちが速いとも言い切れないと思います.
例えば,参照渡ししている方は関数呼び出しが発生したり逆参照が発生したりする分遅いかもしれないですが,インライン化バージョンよりコードサイズが小さくなってCPUのキャッシュにコードが乗り,逆に速くなるかもしれない.
そういう微妙な感じではないでしょうか.
本題ではないですが,関数内部で変更しない引数には全部constを付けたほうが,僕は良いと思います.
コード:
int fun1(const int& x) {
return x*x*x;
}
関数定義にはセミコロンを付ける必要ありませんが,QQQさんは関数定義にセミコロンを書いているのが気になりました.
Re: 参照とinlineとの違い
Posted: 2012年1月23日(月) 09:53
by QQQ
皆さんご指導いただきましてありがとうございます。
beatle 様にご指摘された
「インライン化バージョンよりコードサイズが小さくなってCPUのキャッシュにコードが乗り,逆に速くなるかもしれない.」
ような話は知らなかったので、これこそ大きな事項かもしれませんね。
なぜか、普段こんな議論やお話は少ないですね。
これまで「参照」というやつは本質的にには「別名」だと思っていました。
したがって、コンパイラーは参照名を見たら、元の変数に置き換えるだけで、
関数の引数に現れても、それをaccessにはstack操作一切しないで、
inline 関数と同じ速度で関数が実行されるかなと考えていましたが、
概念的に間違ったのでしょうか。
またどうぞよろしくお願いします。
Re: 参照とinlineとの違い
Posted: 2012年1月23日(月) 10:46
by beatle
概念的には別名という認識でOKなのですが,コンパイラの実装はポインタとほとんど同じ場合が多いということですね.
結局,インライン化しない関数が参照型の引数を受け取る場合,元の変数の場所を知らなければなりませんから,ポインタみたいな実装になってしまうんです.
関数自体の機械語を関数呼び出しごとに変えるなんてことはできませんので.
Re: 参照とinlineとの違い
Posted: 2012年1月23日(月) 10:58
by softya(ソフト屋)
QQQ さんが書きました:皆さんご指導いただきましてありがとうございます。
beatle 様にご指摘された
「インライン化バージョンよりコードサイズが小さくなってCPUのキャッシュにコードが乗り,逆に速くなるかもしれない.」
ような話は知らなかったので、これこそ大きな事項かもしれませんね。
なぜか、普段こんな議論やお話は少ないですね。
インライン化はコンパイラ任せですので、場合によりインライン化されないこともあります。
コンパイラの種類やコンパイルの最適化オプションでも変わります。速度優先かサイズ優先か違いますね。
なので経験で大体どうなるかは想像するしか無いです。
あとは、毎回アセンブラリストを出力するオプションを指定してアセンブラリストを眺めるかです。
なぜ、こんな議論が少ないかというとそれ以前のデータ構造やアルゴリズムの問題で速度低下する事が多いからでしょう。
ここまで考えて調整できる人は自分で何とかできますから。
QQQ さんが書きました:
これまで「参照」というやつは本質的にには「別名」だと思っていました。
したがって、コンパイラーは参照名を見たら、元の変数に置き換えるだけで、
関数の引数に現れても、それをaccessにはstack操作一切しないで、
inline 関数と同じ速度で関数が実行されるかなと考えていましたが、
概念的に間違ったのでしょうか。
それこそアセンブラのリスト見てください。
時間計測とアセンブラリストを見ずに最適化は語れません。