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