3

Intelの数学カーネルライブラリ(MKL)がインストールされた「Anaconda」Pythonディストリビューションを備えたUbuntu 14.04があります。私のプロセッサは、8 コアの Intel Xeon であり、ハイパースレッディングはありません (つまり、8 スレッドのみ)。

私にとって numpyは、大規模な配列に対してtensordot一貫して優れています。einsumただし、他の人は、2つの間にほとんど違いがないこと、または一部の操作で einsum が numpy よりも優れていることさえ発見しています。

高速ライブラリで構築されたディストリビューションを使用している人々にとってnumpy、なぜこれが起こるのか疑問に思っています. インテル以外のプロセッサーでは、MKL の実行速度が遅くなりますか? それともeinsum、より優れたスレッド機能を備えた最新の Intel プロセッサでより高速に動作しますか?

私のマシンでのパフォーマンスを比較するための簡単なコード例を次に示します。

In  [27]: a = rand(100,1000,2000)

In  [28]: b = rand(50,1000,2000)

In  [29]: time cten = tensordot(a, b, axes=[(1,2),(1,2)])
CPU times: user 7.85 s, sys: 29.4 ms, total: 7.88 s
Wall time: 1.08 s

In  [30]: "FLOPS TENSORDOT: {}.".format(cten.size * 1000 * 2000 / 1.08)
Out [30]: 'FLOPS TENSORDOT: 9259259259.26.'

In  [31]: time cein = einsum('ijk,ljk->il', a, b)
CPU times: user 42.3 s, sys: 7.58 ms, total: 42.3 s
Wall time: 42.4 s

In  [32]: "FLOPS EINSUM: {}.".format(cein.size * 1000 * 2000 / 42.4)
Out [32]: 'FLOPS EINSUM: 235849056.604.'

tensordot を使用したテンソル演算は、一貫して 5 ~ 20 GFLOP の範囲で実行されます。私は einsum で 0.2 GFLOPS しか得られません。

4

1 に答える 1

2

基本的に、2 つの非常に異なるものを比較しています。

  • np.einsumC のループでテンソル積を計算しforます。SIMD 最適化がいくつかありますが、マルチスレッドではなく、MLK を使用しません。

  • np.tensordotこれは、入力配列を再形成/ブロードキャストし、行列乗算のために BLAS (MKL、OpenBLAS など) を呼び出すことで構成されます。再形成/ブロードキャスト フェーズにより、追加のオーバーヘッドが発生しますが、 行列の乗算は、SIMD、一部のアセンブラー、およびマルチスレッドで非常に最適化されています。

その結果、小さな配列サイズが使用されない限り、シングル コア実行tensordot よりも一般的に高速になります einsum(その後、再形成/ブロードキャストのオーバーヘッドが無視できなくなります)。前者のアプローチはマルチスレッドであり、後者はそうではないため、これはさらに当てはまります。

結論として、得られる結果は完全に正常であり、おそらく一般的に正しいでしょう (Intel/非 Intel CPU、最新かどうか、マルチコアかどうか、MKL または OpenBLAS の使用など)。

于 2015-07-02T15:10:19.800 に答える