ループアンローリングとデータハザードのデモをPerlでやってみた

2009年3月26日
| コメント(0) | トラックバック(0) ループアンローリングとデータハザードのデモをPerlでやってみた

先日のKansai.pmで発表されていた、ループアンローリングを試してみた。

発表のスライド:Cell Challenge 2009 参加記
Wikipedia:ループ展開 - Wikipedia

ループアンローリング自体はWikipediaによればループ展開ということだが、目的としてはデータハザード(データ依存のために計算の並列処理が不可能になること)をなるべく回避するのが目的であった。
スライドの30枚目に展開の方法が書いてるので、それを実際に試してみた。

以下、ベンチマークの結果

Benchmark: running Unrolling1, Unrolling2, normal for at least 3 CPU seconds...
Unrolling1:  3 wallclock secs ( 3.00 usr +  0.00 sys =  3.00 CPU) @ 429810.06/s (n=1289860)
Unrolling2:  4 wallclock secs ( 3.05 usr +  0.00 sys =  3.05 CPU) @ 444432.88/s (n=1354187)
    normal:  3 wallclock secs ( 3.01 usr +  0.00 sys =  3.01 CPU) @ 210117.41/s (n=633504)
               Rate     normal Unrolling1 Unrolling2
normal     210117/s         --       -51%       -53%
Unrolling1 429810/s       105%         --        -3%
Unrolling2 444433/s       112%         3%         --

Unrolling1は普通に展開したもの。
Unrolling2が展開後に計算順序を入れ替えたもの。
normalは普通のforループ。

計算の順序を入れ替えると、ほんの少しだが速くなった。
多少なりともデータハザードがある、ということなのだろう。

ソースは以下のとおり。

use strict;
use warnings;
use Benchmark qw(:all);
 
our @la = (1 .. 5);
our @lb = (4 .. 8);
 
cmpthese(
    timethese(
        0, # 0 is auto
        {
            normal => sub {
                my (@lc, @ld);
                for my $i (0 .. 4) {
                    $lc[$i] = $la[$i] + $lb[$i];
                    $ld[$i] = $lc[$i] * $lc[$i];
                }
            },
            Unrolling1 => sub {
                my (@lc, @ld);
                $lc[0] = $la[0] + $lb[0];
                $ld[0] = $lc[0] * $lc[0];
                $lc[1] = $la[1] + $lb[1];
                $ld[1] = $lc[1] * $lc[1];
                $lc[2] = $la[2] + $lb[2];
                $ld[2] = $lc[2] * $lc[2];
                $lc[3] = $la[3] + $lb[3];
                $ld[3] = $lc[3] * $lc[3];
                $lc[4] = $la[4] + $lb[4];
                $ld[4] = $lc[4] * $lc[4];
            },
            Unrolling2 => sub {
                my (@lc, @ld);
                $lc[0] = $la[0] + $lb[0];
                $lc[1] = $la[1] + $lb[1];
                $lc[2] = $la[2] + $lb[2];
                $lc[3] = $la[3] + $lb[3];
                $lc[4] = $la[4] + $lb[4];
                $ld[0] = $lc[0] * $lc[0];
                $ld[1] = $lc[1] * $lc[1];
                $ld[2] = $lc[2] * $lc[2];
                $ld[3] = $lc[3] * $lc[3];
                $ld[4] = $lc[4] * $lc[4];
            },
        }
    )
);

トラックバック(0)

このブログ記事に対するトラックバックURL:

コメントする

Google検索

Last.fm

このブログ記事について

このページは、のぶりんが2009年3月26日 23:10に書いたブログ記事です。

ひとつ前のブログ記事は「Text::MicroTemplateの秘密」です。

次のブログ記事は「最近使っているPerlスクリプトのひな形」です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

Creative Commons License
このブログのライセンスは クリエイティブ・コモンズライセンス.
Powered by Movable Type