目次

4. 配列計算

リスト4-1にベクトル和とベクトル内積のソースコードを示します。
MATLABとOctaveのソースコードは同じです。 Scilabでは拡張子を.mから.sceに変え、コメント行の先頭を%から//に変えてください。
表4-1にソースコードの各部の処理内容を示します。 ベクトル和は2通りで、ベクトル内積は3通りで計算します。

表4-1 処理内容
記号処理内容
(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)

  1. (1-1)と(2-1)ではNo.1~No.4の計算時間がほぼ一定であることから、 for分の処理については特に最適化がされていないと思われる。
  2. (1-2)よりベクトル演算を行うと計算時間が大幅に短縮される。 特に使用メモリーの少ないNo.3,No.4ではキャッシュメモリーが有効利用され計算時間がさらに短縮される。
  3. (2-2)の方法は最適化が不十分であり、 (2-3)の方法でさらに計算時間が大幅に短縮される。
  4. 図4-1から、for文のときは並列化されておらず、 ベクトル演算のときは全スレッドで並列計算されている。
  5. (2-3)の結果はC版[4]の8~16スレッドとほぼ同じであり、 同様にマルチスレッドとSIMDの技術で最適化が行われていると思われる。
  6. 同じ計算を行うときでもアルゴリズムによって計算時間が大きく変わるので、 アルゴリズムの選択が重要である。

Scilab(表4-3、図4-2)

  1. for文を用いて大きなベクトルに値を代入すると非常に時間がかかることに注意。
  2. (1-2),(2-2),(2-3)からベクトル演算はMATLABと同等か数分の1の性能を示す。
  3. 使用メモリーの少ないNo.3,No.4ではキャッシュメモリーが有効利用され計算時間が短縮される。
  4. (2-2)の方法は最適化が不十分であり、 (2-3)の方法でさらに計算時間が短縮される。
  5. 図4-2から、ベクトル演算のときも1スレッドしか使用していない。
  6. 同じ計算を行うときでもアルゴリズムによって計算時間が大きく変わるので、 アルゴリズムの選択が重要である。
  7. 全般的な性能はMATLABに劣る。

Octave(表4-4、図4-3)

  1. for文を用いて大きなベクトルに値を代入すると非常に時間がかかることに注意。
  2. (1-2),(2-2),(2-3)からベクトル演算はMATLABと同等か数分の1の性能を示す。
  3. 使用メモリーの少ないNo.3,No.4ではキャッシュメモリーが有効利用され計算時間が短縮される。
  4. (2-2)の方法は最適化が不十分であり、 (2-3)の方法でさらに計算時間が短縮される。
  5. 図4-3から、ベクトル演算のときも1スレッドしか使用していない。 ((2-3)では2スレッドを使用しているが表4-4のNo.3の通り、かえって遅くなっている)
  6. 同じ計算を行うときでもアルゴリズムによって計算時間が大きく変わるので、 アルゴリズムの選択が重要である。
  7. 全般的な性能はMATLABに劣る。

表4-2 MATLABのベクトル和とベクトル内積の計算時間(倍精度)
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
110,000,0001,0000.00秒0.03秒25.03秒9.41秒20.46秒15.08秒3.55秒
21,000,00010,0000.00秒0.01秒23.85秒8.77秒19.15秒17.63秒2.94秒
3100,000100,0000.00秒0.00秒23.53秒1.62秒19.07秒3.22秒0.30秒
410,0001,000,0000.00秒0.00秒23.11秒4.53秒19.26秒8.42秒1.30秒

表4-3 Scilabのベクトル和とベクトル内積の計算時間(倍精度)
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
110,000,0001,0000.04秒10.30秒不可17.56秒不可31.94秒22.56秒
21,000,00010,0000.01秒1.01秒不可19.00秒不可33.43秒24.73秒
3100,000100,0000.00秒0.10秒不可2.84秒不可17.26秒5.36秒
410,0001,000,0000.00秒0.01秒不可3.66秒不可18.98秒7.53秒

表4-4 Octaveのベクトル和とベクトル内積の計算時間(倍精度)
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
110,000,0001,0000.05秒46.65秒不可24.61秒不可32.18秒3.84秒
21,000,00010,0000.01秒4.67秒不可26.44秒不可33.93秒4.53秒
3100,000100,0000.00秒0.46秒不可5.59秒不可13.11秒8.26秒
410,0001,000,0000.00秒0.04秒不可5.29秒不可16.27秒3.24秒

図4-1 MATLAB使用時のタスクマネージャーのCPU使用率(No.3計算時)

図4-2 Scilab使用時のタスクマネージャーのCPU使用率(No.3計算時)

図4-3 Octave使用時のタスクマネージャーのCPU使用率(No.3計算時)