サイン拡張の必要性は何ですか?[定休日]
-
12-12-2019 - |
質問
次のCコードを考えてみましょう -
char sum_char(char a,char b)
{
char c = a+b;
return c;
}
それは以下を含みます: -
- 2番目のパラメータを符号拡張子に変換します。
- Push signed extension parameter on stack as b.
- 最初のパラメータを符号拡張子に変換します。
- としてスタックに署名された拡張パラメータをプッシュ.
- A&b、結果キャストをcharに追加し、それをcに格納します。
- Cは再び符号拡張されています。
- 符号拡張cは戻り値レジスタにコピーされ、関数は呼び出し元に戻ります。
- 結果の呼び出し元関数を格納するには、intをcharに再度変換します。
私の質問は -
- 誰がこれをしますか?
- これほど多くの回心を行う必要性は何ですか?
- マシン/コンパイラのパフォーマンスを低下/向上させますか?
- パフォーマンスを低下させている場合、パフォーマンスを向上させるにはどうすればよいですか?
解決
- 誰がこれをしますか? -最終的には、これを行うのはCPUです;コンパイラは、変換を実行するためにCPUに関連するすべての命令を生成します
- これほど多くの回心を行う必要性は何ですか? -変換は、複数のCコンパイラでサポートされている複数のプラットフォーム間で結果の一貫性を確保するために必要です。
- マシン/コンパイラのパフォーマンスを低下/向上させますか? -これは「何もしない」と比較してパフォーマンスを低下させますが、誰も違いに気付くことはありません。
- パフォーマンスを低下させている場合、パフォーマンスを向上させるにはどうすればよいですか? -何もない:算術演算を実行する必要がある場合は、次のようにします
char
s、次に算術演算を実行しますchar
s.オプティマイザがプラットフォームの不要な指示をすべて削除するようにしてください。ほとんどの場合、CPUにはC言語で必要とされるセマンティックと互換性のある命令があるため、生成されるコードは非常に短くなります。
もちろん、符号付き文字に対して操作を実行する必要がない場合は、符号なし文字に対して操作を実行できます。これにより、かなりのサイン拡張が排除されました。
他のヒント
記述する変換は、抽象マシンでのみ実行されます。コンパイラは、同じ観測可能な動作につながる場合、これらすべてをショートカットできます。
最適化をオンにすると、私のコンパイラはこれを次のアセンブラに変換します
sum_char:
.LFB0:
.cfi_startproc
leal (%rsi,%rdi), %eax
ret
.cfi_endproc
.LFE0:
.size sum_char, .-sum_char
これはただ一つの追加です(に隠されています leal
命令)とa ret
跳べ!.
- 実行時のコード。コンパイラは、プログラミング言語の指定されたセマンティクスを実装するために必要なコードを生成します。
- あなたが話している「スタック」へのプッシュではわかりませんが、私が知る限り、Cにはそのような要件はありません。
- それは意味をなさない;何に比べて?
- あなたは無意味なものを取り除いてみることができます
c
変数、およびちょうど持っているreturn (char) (a + b);
.そうは言っても、この関数には「最適化」することはあまりないと思います。それは非常に小さなコードにコンパイルする必要があります。あなたがそれをインライン化することができれば、それはおそらく1命令のオーダーになるでしょう。
私はあなたの質問の詳細については不明です。ソースを引用せずにsign-extensionを繰り返し参照します;私はあなたが仮定していると思います char
データ型はCPUのビットネスに一致するように拡張されますが、これがすでにそうではないという保証はないと思います。
しかし、あなたの漠然とした質問に答える際の刺し傷として:
- コンパイラは、コードを書くことに応答してこれを行います。誰がコードを書いていますか?開発者、私は想像するでしょう。 あなた あなたが質問を書いたとき、これをしました。
- 必要性がある場合(ソースを引用しないため)、CPUが算術演算をネイティブに処理できるようにするためだと思います。
- 技術的にはそれを減らすでしょうが、任意のビットネスを持つ理論的なマシンと比較するだけです。現実的には、それは顕著な違いはありません。
- アーキテクチャのネイティブビットに一致するデータ型を使用すると、パフォーマンスがわずかに向上します。しかし、これは 非常に わずかで、通常は不便に値するものではありません。
所属していません StackOverflow