リスト4-1にベクトル和とベクトル内積のソースコードを示します。
MATLABとOctaveのソースコードは同じです。
Scilabでは拡張子を.mから.sceに変え、コメント行の先頭を%から//に変えてください。
表4-1にソースコードの各部の処理内容を示します。
ベクトル和は2通りで、ベクトル内積は3通りで計算します。
記号 | 処理内容 |
---|---|
(0-1) | ベクトルの宣言 |
(0-2) | ベクトルへの値の代入 |
(1-1) | ベクトル和の計算、for文使用 |
(1-2) | ベクトル和の計算、ベクトル演算使用、a+b |
(2-1) | ベクトル内積の計算、for文使用 |
(2-1) | ベクトル内積の計算、ベクトル要素ごとに掛け算を行い、その後ベクトルの和をとる、sum(a.*b) |
(2-3) | ベクトル内積の計算、行ベクトルaを転置して列ベクトルにし、行ベクトルbとの積を求める、a'*b |
リスト4-1 ベクトル和とベクトル内積のソースコード (benchmark.m)
1 clear all 2 3 N = 100000; 4 L = 100000; 5 6 % (0-1) alloc 7 tic 8 a = zeros(N, 1); 9 b = zeros(N, 1); 10 c = zeros(N, 1); 11 toc 12 13 % (0-2) setup 14 tic 15 for i = 1 : N 16 a(i) = i; 17 b(i) = i; 18 end 19 toc 20 21 % (1) vadd 22 % (1-1) for 23 tic 24 for l = 1 : L 25 for i = 1 : N 26 c(i) = a(i) + b(i); 27 end 28 end 29 toc 30 31 % (1-2) c = a + b 32 tic 33 for l = 1 : L 34 c = a + b; 35 end 36 toc 37 38 % (2) sdot 39 % (2-1) for 40 tic 41 s = 0; 42 for l = 1 : L 43 for i = 1 : N 44 s = s + a(i) * b(i); 45 end 46 end 47 toc 48 49 % (2-2) sum(a .* b) 50 tic 51 s = 0; 52 for l = 1 : L 53 s = s + sum(a .* b); 54 end 55 toc 56 57 % (2-3) a' * b 58 tic 59 s = 0; 60 for l = 1 : L 61 s = s + (a' * b); 62 end 63 toc
表4-2~表4-4にMATLAB,Scilab,Octaveの計算時間を示します。
計算時間の誤差を小さくするために繰り返し回数分だけ計算しています。
ベクトルの大きさNと繰り返し回数Lの積はNo.1~No.4で一定1010です。
従ってNo.1~No.4の演算量は同じです。
最適化の効果が見られるケースに色をつけています。
ScilabとOctaveでは表3-1の通り大きなベクトルに値を代入すると非常に時間がかかるため、
ここでは(1-1)と(2-1)は計測していません。
図4-1~図4-3にそれぞれのケースのNo.3計算時のタスクマネージャーのCPU使用率を示します。
計算に使用したCPUは8コア16スレッドであるために、CPU使用率は、
1スレッド使用時は6%、16スレッド使用時に100%となります。
なお、MATLABでは "maxNumCompThreads(8)"
等で使用する最大スレッド数を制限することができます。既定値は物理コア数です。
これらの結果から各ソフトウェアについて以下のことが言えます。
MATLAB(表4-2、図4-1)
Scilab(表4-3、図4-2)
Octave(表4-4、図4-3)
No. | ベクトルの大きさN | 繰り返し回数L | 準備 | ベクトル和 | ベクトル内積 | ||||
---|---|---|---|---|---|---|---|---|---|
(0-1) zeros | (0-2) 代入 | (1-1) for文 | (1-2) a+b | (2-1) for文 | (2-2) sum(a.*b) | (2-3) a'*b | |||
1 | 10,000,000 | 1,000 | 0.00秒 | 0.03秒 | 25.03秒 | 9.41秒 | 20.46秒 | 15.08秒 | 3.55秒 |
2 | 1,000,000 | 10,000 | 0.00秒 | 0.01秒 | 23.85秒 | 8.77秒 | 19.15秒 | 17.63秒 | 2.94秒 |
3 | 100,000 | 100,000 | 0.00秒 | 0.00秒 | 23.53秒 | 1.62秒 | 19.07秒 | 3.22秒 | 0.30秒 |
4 | 10,000 | 1,000,000 | 0.00秒 | 0.00秒 | 23.11秒 | 4.53秒 | 19.26秒 | 8.42秒 | 1.30秒 |
No. | ベクトルの大きさN | 繰り返し回数L | 準備 | ベクトル和 | ベクトル内積 | ||||
---|---|---|---|---|---|---|---|---|---|
(0-1) zeros | (0-2) 代入 | (1-1) for文 | (1-2) a+b | (2-1) for文 | (2-2) sum(a.*b) | (2-3) a'*b | |||
1 | 10,000,000 | 1,000 | 0.04秒 | 10.30秒 | 不可 | 17.56秒 | 不可 | 31.94秒 | 22.56秒 |
2 | 1,000,000 | 10,000 | 0.01秒 | 1.01秒 | 不可 | 19.00秒 | 不可 | 33.43秒 | 24.73秒 |
3 | 100,000 | 100,000 | 0.00秒 | 0.10秒 | 不可 | 2.84秒 | 不可 | 17.26秒 | 5.36秒 |
4 | 10,000 | 1,000,000 | 0.00秒 | 0.01秒 | 不可 | 3.66秒 | 不可 | 18.98秒 | 7.53秒 |
No. | ベクトルの大きさN | 繰り返し回数L | 準備 | ベクトル和 | ベクトル内積 | ||||
---|---|---|---|---|---|---|---|---|---|
(0-1) zeros | (0-2) 代入 | (1-1) for文 | (1-2) a+b | (2-1) for文 | (2-2) sum(a.*b) | (2-3) a'*b | |||
1 | 10,000,000 | 1,000 | 0.05秒 | 46.65秒 | 不可 | 24.61秒 | 不可 | 32.18秒 | 3.84秒 |
2 | 1,000,000 | 10,000 | 0.01秒 | 4.67秒 | 不可 | 26.44秒 | 不可 | 33.93秒 | 4.53秒 |
3 | 100,000 | 100,000 | 0.00秒 | 0.46秒 | 不可 | 5.59秒 | 不可 | 13.11秒 | 8.26秒 |
4 | 10,000 | 1,000,000 | 0.00秒 | 0.04秒 | 不可 | 5.29秒 | 不可 | 16.27秒 | 3.24秒 |