web-dev-qa-db-ja.com

int by intと比較して、float by float行列の乗算を実行する方が速いのはなぜですか?

1000行と10K列を超える2つのint行列AとBがあるので、高速化(4倍以上)を得るためにそれらをfloat行列に変換する必要があることがよくあります。

なぜそうなのかしら?浮動小数点行列の乗算では、AVXなどの最適化とベクトル化が数多く行われていることに気付きました。しかし、それでも、整数用のAVX2などの命令があります(私が間違っていない場合)。そして、整数にSSEとAVXを利用することはできませんか?

NumpyやEigenなどの行列代数ライブラリの下にこれをキャプチャしてfloatのように整数行列乗算をより高速に実行するヒューリスティックがないのはなぜですか?

受け入れられた回答について: @saschaの回答は非常に有益で関連性がありますが、@ chatzの回答は、BLAS整数行列演算が存在するかどうかに関係なく、int byint乗算が遅い実際の理由です。

25
NULL

基本的に製品を計算するだけのこれら2つの単純な関数をコンパイルする場合(Eigenライブラリを使用)

#include <Eigen/Core>

int mult_int(const Eigen::MatrixXi& A, Eigen::MatrixXi& B)
{
    Eigen::MatrixXi C= A*B;
    return C(0,0);
}

int mult_float(const Eigen::MatrixXf& A, Eigen::MatrixXf& B)
{
    Eigen::MatrixXf C= A*B;
    return C(0,0);
}

フラグを使用する-mavx2 -S -O3整数バージョンと浮動小数点バージョンについて、非常によく似たアセンブラコードが表示されます。ただし、主な違いは、vpmulldのレイテンシが2〜3倍で、スループットがvmulpsの1/2または1/4しかないことです。 (最近のIntelアーキテクチャについて)

参照: Intel Intrinsics Guide 、「スループット」とは、相互スループット、つまり、遅延が発生しない場合(多少簡略化されている場合)の操作ごとに使用されるクロックサイクル数を意味します。

13
chtz

これらのベクトルベクトルおよび行列ベクトル演算はすべて、内部で [〜#〜] blas [〜#〜] を使用しています。さまざまなアーチ、CPU、命令、およびキャッシュサイズ用に数十年にわたって最適化されたBLASには、整数型はありません。

ここにOpenBLASのいくつかのブランチがあります それに取り組んでいます(そしていくつか それをリンクしているグーグルグループでの小さな議論 )。

そして、私はIntelのMKL(IntelのBLAS実装)を聞いたと思います 整数型でも機能している可能性がありますこの講演 面白そうです(そのフォーラムで言及されています)が、短く、おそらくより接近している小さな整数型は埋め込みディープで役立ちます-学習)。

15
sascha