Scipy/SK-learn/C++/CUDA/Python K-Means benchmark

python,scikit-learn, scipy, C++, CUDA Cのk-meansベンチマーク用コードがあったのでやってみた。benchmark codeはこのサイトから拝借させてもらった。

先ず以下のサイトからベンチ用コードをダウンロードする。

%download https://raw.githubusercontent.com/goldsborough/k-means/master/python/k_means.py
Downloaded 'k_means.py'.

次にテストに使用するデータをダウンロードしてくる。

%download https://github.com/goldsborough/k-means/blob/master/data/100k.csv?raw=true
Downloaded '100k.csv'.

次にダウンロードしたコードを以下のようにして実行する。

!python k_means.py -k 5 -d 100k.csv -m scipy -i 300 -r 5
Took 0.99973435s (5 runs)

k = 5, data = 100000, method = scipy, iteration = 300, run = 5の条件で走らせたベンチマークの結果は約1秒だった。

K-Means benchmark(Scikit-learn編)

Scikit-learnもScipyと同じ条件でベンチを走らせる。

!python k_means.py -k 5 -d 100k.csv -m sklearn -i 300 -r 5
Took 0.94455233s (5 runs)

scikit-learnはscipyよりもほんのちょい速い結果になった。正確に言うと、

0.99973435/0.94455233
1.0584213476028375

scikit-learnはscipyよりも1.06倍処理が高速だった。

K-Means benchmark(Python編)

pythonもscikit-learnやScipyと同じ条件でベンチを走らせる。

!python k_means.py -k 5 -d 100k.csv -m custom -i 300 -r 5
Took 4.23686709s (5 runs)

予想通りpythonは一番の鈍足だった。これまで最速のsk-learnに比べ

4.23686709/0.94455233
4.485582169915349

4.5倍も実行速度が遅かった。と言っても実際にはnumpyっぽい。

K-Means benchmark(C++編)

先ず下記のサイトからC++ベンチコードをダウンロードしてくる。

%download https://raw.githubusercontent.com/goldsborough/k-means/master/cpp/k-means.cpp
Downloaded 'k-means.cpp'.
!g++ -O3 -std=c++11 k-means.cpp -o kmeans

usage: k_means data-file k iterations runsの書式に合わせて実行する。

!./kmeans 100k.csv 5 300 5
Took: 0.205814s (5 runs)
-9.59979 -7.30149
4.61188 -8.90389
-5.85912 -0.217544
-5.08502 -9.91363
3.22232 -10.0933
0.94455233/0.205814
4.589349266813725

C++版はこれまで最速のSK-learn版より4.6倍も処理が高速だった。

C++Eigen編

%download https://raw.githubusercontent.com/goldsborough/k-means/master/cpp/k-means-eigen.cpp
Downloaded 'k-means-eigen.cpp'.
!g++ -O3 -std=c++11 k-means-eigen.cpp -o k-means-eigen
k-means-eigen.cpp:1:23: fatal error: Eigen/Dense: No such file or directory
compilation terminated.

Eigen/Denseヘッダーファイルが探せないみたいなので教えてあげる。

!g++ -O3 -std=c++11 -I/usr/local/include/eigen3/ k-means-eigen.cpp -o k-means-eigen
!./k-means-eigen 100k.csv 5 300 5
Took: 0.723949s (5 runs)
-5.8588 -0.21753
4.6124 -8.9047
-9.5993 -7.3011
-5.0848 -9.9131
3.2211 -10.092

苦労の割に、かなり期待はずれの結果に終わった。

K-Means benchmark(CUDA C編)

%download https://raw.githubusercontent.com/goldsborough/k-means/master/cuda/k-means-simple-sm.cu
Downloaded 'k-means-simple-sm.cu'.
!nvcc -O2 -std=c++11 k-means-simple-sm.cu -o gpu
!./gpu 100k.csv 5 300 5
Processing 100000 points on 98 blocks x 1024 threads
Took: 0.0591697s
-5.85913 -0.217544
4.6126 -8.90514
3.2212 -10.0925
-9.59979 -7.3015
-5.08501 -9.91362
0.205814/0.0591697
3.4783681512666114

CUDA版は実行速度がC++版の3.5倍高速だった。

CUDA/C バージョン2

%download https://raw.githubusercontent.com/goldsborough/k-means/master/cuda/k-means-fast.cu
Downloaded 'k-means-fast.cu'.
!nvcc -O3 -std=c++11 k-means-fast.cu -o k-means-fast
!./k-means-fast 100k.csv 5 300 5
Processing 100000 points on 98 blocks x 1024 threads
Took: 0.0358488s
-6.58174 -0.296216
3.93247 -9.4968
-5.02863 -9.93007
-4.98512 -0.24325
-9.54836 -7.40937
0.0591697/0.0358488
1.6505350248822834

バージョン2はバージョン1よりも約1.7倍処理が高速だった。