私は、ハードウェアで変換が発生する可能性があるため、この質問に対する回答はターゲットアーキテクチャによって異なると思われます。例えば、int型とフロートの間にいくつかの相互変換が発生し、次のコードを、考えてみましょう。私はデフォルト設定で(私はUbuntuの、x86でよ)++グラムでこれをコンパイルしようとした、と分解し、GDBを使用
int main (int argc, char** argv)
{
int precoarced = 35;
// precoarced gets forced to float
float result = 0.5 + precoarced;
// and now we force it back to int
return (int)result;
// I wonder what the disassembly looks like in different environments?
}
:
0x00000000004004b4 <+0>: push %rbp
0x00000000004004b5 <+1>: mov %rsp,%rbp
0x00000000004004b8 <+4>: mov %edi,-0x14(%rbp)
0x00000000004004bb <+7>: mov %rsi,-0x20(%rbp)
0x00000000004004bf <+11>: movl $0x23,-0x8(%rbp)
0x00000000004004c6 <+18>: cvtsi2sdl -0x8(%rbp),%xmm0
0x00000000004004cb <+23>: movsd 0x10d(%rip),%xmm1 # 0x4005e0
0x00000000004004d3 <+31>: addsd %xmm1,%xmm0
0x00000000004004d7 <+35>: unpcklpd %xmm0,%xmm0
0x00000000004004db <+39>: cvtpd2ps %xmm0,%xmm0
0x00000000004004df <+43>: movss %xmm0,-0x4(%rbp)
0x00000000004004e4 <+48>: movss -0x4(%rbp),%xmm0
0x00000000004004e9 <+53>: cvttss2si %xmm0,%eax
0x00000000004004ed <+57>: pop %rbp
0x00000000004004ee <+58>: retq
cvt接頭辞付きニーモニックの説明に注意してください。これらは変換の指示です。そのため、この場合、ハードウェアでの変換はいくつかの命令で行われています。したがって、これらの命令のコストはどれくらいのサイクルになるかによって、かなり高速になる可能性があります。しかし、やはり異なるアーキテクチャー(または別のコンパイラー)がストーリーを変える可能性があります。
編集:面白いことに、誤って0.5fの代わりに0.5を指定してしまったため、そこに追加の変換があります。それがcvtpd2psオペレーションがそこにある理由です。
編集:x86は長い間(80年代以降)FPをサポートしていたので、x86をターゲットとしたC++コンパイラは一般的にハードウェアを使用します(コンパイラが時代遅れでない限り)。これを指摘してくれたHot Licksに感謝します。
はい、異種間の変換には費用がかかります。私は私の中期から帰ってくるまでに他の人がいなければ、詳細な答えを出すかもしれません。 – Mysticial
浮動小数点演算は基本2算術の点では自明ではないので、コンパイラはヘルパー関数を発行することが多く(libgccが必要な理由を参照)、パフォーマンスに重大な影響を与えることがあります。 –
問題は、あなたのプログラムは、異なるタイプのオペランドに対してn-ary演算をしないことです。それは、例えば、 C99の6.3.1。通常は同じタイプの引数を使用してn-ary演算が実行されます(例外はいくつかありますが、浮動小数点型は含まれません)。 –