リスト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秒 |