3

新しい Intel の Sandy Bridge プロセッサで AVX 命令をいじり始めました。MinGW64のGCC 4.5.2、TDM-GCC 64ビットビルドを使用しています。

ostream が vector typesなどをコンソール__m256に出力できるように、operator<< をオーバーロードしたいと考えています。__m128しかし、私は過負荷の競合に遭遇しています。次のコードの 2 番目の関数は、「以前の宣言と競合しています」というエラーを生成しますvoid f(__vector(8) float)

void f(__m128 v) {
cout << 4;
}

void f(__m256 v) {
    cout << 8;
}

コンパイラは 2 つのタイプを区別できず、両方を考慮しているようf(float __vector)です。

これを回避する方法はありますか?私はオンラインで何も見つけることができませんでした。どんな助けでも大歓迎です。

4

2 に答える 2

4

関数テンプレートで同様の問題が発生したときに、偶然答えに出くわしました。この場合、GCC エラー メッセージは実際に解決策を示しています。

-fabi-version=4コンパイラ オプションを追加します。

これで問題は解決し、標準ライブラリをリンクするときに問題が発生しないことを願っています。

ABI ポリシーとガイドラインおよびABI 仕様で、ABI (Application Binary Interface) と GCC について詳しく読むことができます。ABI は、コードがオブジェクト ファイルにコンパイルされるときに、関数名がどのようにマングルされるかを指定します。どうやら、デフォルトで GCC によって使用される ABI バージョン 3 は、さまざまなベクター型を区別できません。

于 2011-05-10T07:01:27.247 に答える
1

これを解決するためにコンパイラの ABI フラグを変更するという解決策には満足できなかったので、別の解決策を探しました。Eigen ライブラリの作成中にこの問題が発生したようです。詳細については、このソース ファイルを参照してくださいhttp://eigen.tuxfamily.org/dox-devel/SSE_2PacketMath_8h_source.html

これに対する私の解決策は、彼らのものをわずかに調整したバージョンです。

template <typename T, unsigned RegisterSize>
struct Register
{
    using ValueType = T;
    enum { Size = RegisterSize };

    inline operator T&() { return myValue; }
    inline operator const T&() const { return myValue; }
    inline Register() {}
    inline Register(const T & v) : myValue(v) {} // Not explicit
    inline Register & operator=(const T & v)
    {
        myValue = v;
        return *this;
    }

    T myValue;
};

using Register4 = Register<__m128, 4u>;
using Register8 = Register<__m256, 8u>;
// Could provide more declarations for __m128d, __m128i, etc. if needed

Register4上記を使用すると、 、 などをオーバーロードしたり、リンクの問題に遭遇したり、ABI 設定を変更したりすることなく、 を使用Register8するテンプレート関数を生成できます。Register

于 2014-12-04T14:53:32.987 に答える