1

こんにちは、私はさらに別の任意精度整数ライブラリに取り組んでいます。乗算を実装したかったのですが、機能しなかったとき_m_pmulhwに行き詰まりました。MMX 命令に関するドキュメント<mmintrin.h>はほとんどありません。私がテストすると、2 つの UINT64_MAX を乗算すると意味不明になります。

uint_fast64_t mulH(const uint_fast64_t &a, const uint_fast64_t &b)  {  
    return (uint_fast64_t)_m_pmulhw((__m64)a,(__m64)b);
}
uint_fast64_t mulL(const uint_fast64_t &a, const uint_fast64_t &b)  {  
    return (uint_fast64_t)_m_pmullw((__m64)a,(__m64)b);
}
int main() {
    uint64_t a = UINT64_MAX;
    uint64_t b = UINT64_MAX;
    std::cout <<  std::bitset<64>(mulH(a,b)) << std::bitset<64>(mulL(a,b));
}

output: 00000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000100000000000000010000000000000001 

A6-4400M APU を使用しているのに、なぜ機能しないのかわかりません...

coreinfo の出力:MMX * Supports MMX instruction set

したがって、サポートされていないわけではないと言えると思います。誰かがこれを機能させる方法についてのヒントを教えてくれたら、ありがとう。

コンパイラ: gcc

IDE: ビジュアル スタジオ コード

4

2 に答える 2

2

私はこれの専門家ではありませんが、https://www.felixcloutier.com/x86/pmulhw によるとこれらの命令は 64x64->128 の乗算を行いません。4 つの 16x16->32 乗算を行います。説明の「梱包済み」という言葉に注意してください。さらに、それは符号付き乗算です。

したがって、64 ビットUINT64_MAX値は の 4 つの単語、つまり として解釈され0xffffます-1。つまり、 を 4 回掛け-1ています。-1もちろん、それぞれの数値の答えは1です。pmulhw命令の結果は、結果の上位半分 (つまり の 4 ワード0x0000) でありpmullw、下位半分 (つまり の 4 ワード0x0001) です。

これはまさにあなたが得たものなので、指示は完全に機能しているように思えます.

2 つの 64 ビット整数の符号なし乗算を実行したい場合は、昔ながらの普通のmul命令が目的を果たします。gccそれを生成する最も簡単な方法は、おそらく入力を__uint128_t通常の*演算子にキャストして乗算することです。

于 2020-02-19T04:29:36.180 に答える