ページ 1 / 1
boolからintへのキャストの仕組み
Posted: 2012年11月24日(土) 17:47
by dom
投機実行などを考慮するとif文は無いほうが良いので、boolからintへのキャストを利用して、例えば以下のように書くことができます。
コード:
// ノーマル
double max(double x, double y)
{
if (x >= y) return x;
else return y;
}
// bool => int のキャスト使用
double max(double x, double y)
{
int b = static_cast<int>(x >= y);
return b * x + (1-b) * y;
}
ここで質問なのですが、キャスト自体が「boolが真なら1、偽なら0」というように分岐の要素を含んでいますが、実際に内部で分岐が行われているのでしょうか?それとも、ハードでビット演算的に計算されているのでしょうか?
Re: boolからintへのキャストの仕組み
Posted: 2012年11月24日(土) 17:51
by softya(ソフト屋)
条件比較自体が機械語レベルの分岐を必要とするので前提自体が破綻しているかと。
まぁ、CPUやC++の実装でも変わりそうなので気にするならアセンブラで書けって事になるレベルでしょうか。
つまり、高級言語で気にしすぎです。
[修正]
あとreturnと演算のコストも秤にかける必要があるでしょう。
やるなら、実測と最適化の掛かったリリースビルド時のアセンブラコードを見比べてみる必要があるでしょう。
私なら分かりづらい後者を使うことはないと思います。
Re: boolからintへのキャストの仕組み
Posted: 2012年11月24日(土) 18:07
by beatle
softya(ソフト屋) さんが書きました:条件比較自体が機械語レベルの分岐を必要とするので前提自体が破綻しているかと。
必ずしもそうではないのでは?
例えば引き算した結果のボロービットを1,0として扱えば、分岐なしで行けるような気はします。
C++の規格を読んでみましたが、falseは0に、trueは1に変換されるよと書いてあるだけで、false/trueの内部表現は特に規定されていないようなので、
もしかしたらtrue/falseを1/0以外で表す処理系もあるかもしれませんね。
そのような処理系だったらstatic_castしようが条件分岐が発生する可能性はあります。
Re: boolからintへのキャストの仕組み
Posted: 2012年11月24日(土) 18:15
by softya(ソフト屋)
beatle さんが書きました:必ずしもそうではないのでは?
例えば引き算した結果のボロービットを1,0として扱えば、分岐なしで行けるような気はします。
確かにレジスタ転送、シフトやAND演算だけでもいけそうなCPUがある気がしますね。
例えばvc++だと、どんな実装をされているか気になるところですが、実装を前提にすると大体後で困るので気にしない方が正しい組み方ですよね。
実際にアセンブルコードを確認することはできますが実用性はないかと。
【補足】
試してみましたが、VC++2008はjbを選びましたね。
コンパイルのコマンド:cl /O2 /FAcs a.cpp
コード:
bool max(double x, double y)
{
return x >= y;
}
コード:
; Listing generated by Microsoft (R) Optimizing Compiler Version 15.00.30729.01
include listing.inc
INCLUDELIB LIBCMT
INCLUDELIB OLDNAMES
PUBLIC ?max@@YA_NNN@Z ; max
EXTRN _fltused:DWORD
; Function compile flags: /Ogtpy
; File c:\cygwin\home\softyasu\a.cpp
; COMDAT ?max@@YA_NNN@Z
_TEXT SEGMENT
x$ = 8
y$ = 16
?max@@YA_NNN@Z PROC ; max, COMDAT
; 3 : return x >= y;
00000 66 0f 2f c1 comisd xmm0, xmm1
00004 72 03 jb SHORT $LN3@max
00006 b0 01 mov al, 1
; 4 : }
00008 c3 ret 0
$LN3@max:
; 3 : return x >= y;
00009 32 c0 xor al, al
; 4 : }
0000b c3 ret 0
?max@@YA_NNN@Z ENDP ; max
_TEXT ENDS
END
Re: boolからintへのキャストの仕組み
Posted: 2012年11月24日(土) 18:40
by dom
返信ありがとうございます。
ttp://bm98.yaneu.com/intensive/tips3.htmlのページを読んで分岐を無くすように意識してたのですが、
確かに気にしすぎでしたね。処理系によるとのことなので、実用上は実際に速度を測ろうと思います。
Re: boolからintへのキャストの仕組み
Posted: 2012年11月24日(土) 18:42
by dom
返信ありがとうございます。
ttp://bm98.yaneu.com/intensive/tips3.html
のページを読んで分岐を無くすように意識してたのですが、
確かに気にしすぎでしたね。処理系によるとのことなので、実用上は実際に速度を測ろうと思います。
Re: boolからintへのキャストの仕組み
Posted: 2012年11月24日(土) 18:47
by softya(ソフト屋)
速度を例え測っても、コンパイラのオプションで出力される機械語が変わります。
あとコンパイラのバージョンでも出力する機械語は変わる可能性があります。
それともうひとつ、CPUの設計で動作が変わるのでCoreiでもバージョンが変わると機械語レベルで分岐予想などの動作が変わってきます。
当然AMDとINTELでは動作が違います。
と言うことを考えだすとキリがないです。
幾つかの環境でテストして差し支えないレベルを目指すほうが実用的です。