MATLAB などの言語でベクトル化を使用すると、ループ変数を維持するオーバーヘッドがなくなり、コードが高速化されることは理解していますが、実際にアセンブリ/マシン コードでベクトル化がどのように行われるのでしょうか? まだどこかにループがなければならないということですよね?
2 に答える
Matlabの「ベクトル化」の概念は、SSEなどのベクトル命令の概念とは完全に異なります。これは、MATLABプログラマーとC/asmプログラマーという2つのグループの人々の間でよくある誤解です。Matlabの「ベクトル化」という言葉は、一般的に使用されているように、ループを行列インデックス(のベクトル)の形式で表現することだけを目的としており、ループを作成する代わりに、基本的な行列/ベクトル操作(BLAS)の観点から物事を作成することもあります。自体。Matlabの「ベクトル化された」コードは、必ずしもベクトル化されたCPU命令として表現されるとは限りません。次のコードを検討してください。
A = rand(1000);
B = (A(1:2:end,:)+A(2:2:end,:))/2;
このコードは、隣接する2つの行列行の平均値を計算します。これは「ベクトル化された」MATLAB式です。ただし、matlabは行列を列ごとに格納するため(列はメモリ内で連続しています)、この操作はSSEベクトルの操作に簡単に変更されません。行方向の操作を実行するため、ベクトルにロードする必要のあるデータは連続して保存されません。メモリ内。
一方、このコードは
A = rand(1000);
B = (A(:,1:2:end)+A(:,2:2:end))/2;
一度に2つの隣接する列を操作するため、SSE命令とストリーミング命令を利用できます。
したがって、matlabの「ベクトル化」はCPUベクトル命令を使用することと同じではありません。これは、MATLABに実装されたループがないことを示すために使用される単語です。混乱を助長するために、arrayfunやbsxfunなどの組み込み関数を使用してループが実装されていると言う人もいます。これらの関数はネイティブのmatlabループよりも大幅に遅い可能性があるため、これはさらに誤解を招く可能性があります。robinceが言ったように、最近のmatlabではすべてのループが遅いわけではありませんが、いつ機能するのか、いつ機能しないのかを知る必要があります。
そして、どのような方法でも常にループが必要です。ループは、ユーザーのmatlabコードではなく、matlabの組み込み関数/BLASに実装されているだけです。
はい、まだループがあります。ただし、コンパイルされたコードで直接ループすることはできます。Fortran (Matlab が元々ベースとしていた) C または C++ のループは、本質的に遅くはありません。Matlab で遅いのは、動的ランタイムの特性です (Python のような他の動的言語でも遅いです)。
Matlab が Just-In-Time コンパイラ ループを導入して以来、パフォーマンスは実際に劇的に向上しました。そのため、ループを回避するための古いガイドラインは、最近のバージョンでは以前ほど重要ではなくなりました。