13

両方の指示について少し混乱しています。最初に、スキャンされた値が 0 で、結果が undefined/bsr または bitsize/lzcnt であるという特殊なケースを破棄しましょう。この違いは明確であり、私の質問の一部ではありません。

バイナリ値を取りましょう0001 1111 1111 1111 1111 1111 1111 1111

Intelの仕様によると、結果lzcntは3です

Intel の仕様によると、結果bsrは 28 です

lzcntカウント、bsrインデックスまたはビット 0 (LSB) からの距離を返します。

利用可能な CPU に BMI がない場合のように、どのように両方の命令を同じにして、どのようlzcntにエミュレートすることができますか? それとも、msbbsrの場合はビット 0ですか? bsrIntel の仕様の両方の「コード操作」も異なります。1 つは左からカウントまたはインデックスを作成し、もう 1 つは右からカウントまたはインデックスを作成します。

誰かがこれに光を当てることができるかもしれません.フォールバックへのフォールバックが同じ結果で機能するBMI/lzcntかどうかをテストするための指示がないCPUはありません(スキャンする値0の特別なケースは決して起こらないため).bsr

4

2 に答える 2

16

LZCNT先行ゼロのビット数を与える。BSR最上位 1 ビットのビット インデックスを返します。したがって、結果の解釈が異なることを除いて、ゼロ以外の場合でも効果的に同じことを行います。したがって、31 から結果を引くだけで、BSRと同じ動作を得ることができます。LZCNTLZCNT == (31 - BSR)

于 2014-09-05T10:28:11.713 に答える
12

明確にするために、からへの有効なフォールバックはありません。何が起こったかというと、Intel は以前の冗長なシーケンスを使用して新しい命令をエンコードしたということです。冗長なプレフィックスを使用することは一般に無視されるように定義されていましたが、将来の CPU では異なる方法でデコードされる可能性があるという警告がありました1lzcntbsrrep bsrlzcntrepbsr

したがってlzcnt、それをサポートしていない CPU で実行すると、bsr. もちろん、このフォールバックは正確には意図的なものではなく、間違った結果をもたらします (Paul R が指摘しているように、同じビットを見て、別の方法で報告します)。これは、新しい命令がエンコードされた方法の結果であり、いかに無意味であるかにすぎません。repプレフィックスは以前の CPU で処理されていました。したがって、ワールドフォールバックlzcntはandにはほとんど完全に不適切ですbsr

tzcntとの場合、状況はより微妙ですbsf。これは同じエンコーディング トリックを使用します: と同じエンコーディングをtzcnt持っていますが、ゼロを除くすべての入力と同じ値を返すためrep bsf、ここでは「フォールバック」がほとんど機能します。入力がゼロの場合、32 が返されますが、bsf は宛先を未定義のままにします。tzcntbsftzcnt

ただし、このフォールバックでさえ実際には使用できません。入力がまったくない場合は、 を使用するだけbsfで、バイトを節約し、数十年の CPU と互換性があり、入力がゼロの場合は動作が異なります。

したがって、動作はおそらくフォールバックよりもトリビアとして分類する方が適切です...


通常、これは多かれ少なかれ難解ですが、たとえば、明示的な命令を挿入せずに後続のコードを整列させるために、命令を長くする機能的な効果がない場所でプレフィックスを使用できrepますnop。「将来的には異なる方法でデコードされる可能性がある」ことを考えると、将来の任意の CPU で実行される可能性のあるコードをコンパイルする場合、これは危険です。

于 2017-04-17T00:47:45.083 に答える