blocked_range2d テンプレート・クラス

概要

再帰的に分割可能な 2 次元の半開区間を表すテンプレート・クラス。

ヘッダー

#include "tbb/blocked_range2d.h"

構文

template<typename RowValue, typename ColValue> class blocked_range2d;

説明

blocked_range2d<RowValue ,ColValue > は、2 次元の半開区間 [i0,j0)×[i1,j1) を表します。範囲の各軸には独自の分割しきい値があります。RowValue および ColValue は、「blocked_range テンプレート・クラス」セクションの表の要件を満たしていなければなりません。いずれかの軸が分割可能な場合、blocked_range2d は分割可能です。blocked_range2d は、Range コンセプトをモデル化します。

メンバー

 
namespace tbb {
template<typename RowValue, typename ColValue=RowValue>
    class blocked_range2d {
    public:
        // 型
        typedef blocked_range<RowValue> row_range_type;
        typedef blocked_range<ColValue> col_range_type;

        // コンストラクター
        blocked_range2d( 
            RowValue row_begin, RowValue row_end, 
            typename row_range_type::size_type row_grainsize,
            ColValue col_begin, ColValue col_end, 
            typename col_range_type::size_type col_grainsize);
        blocked_range2d( RowValue row_begin, RowValue row_end, 
                         ColValue col_begin, ColValue col_end);
        // 分割コンストラクター
        blocked_range2d( blocked_range2d& r, split );
        blocked_range2d( blocked_range2d& r, proportional_split proportion );

        // 比例分割が可能
        static const bool is_splittable_in_proportion = true;

        // キャパシティー
        bool empty() const;

        // アクセス
        bool is_divisible() const;
        const row_range_type& rows() const;
        const col_range_type& cols() const;
    };
}

サンプル

次のコードは、シリアル行列乗算と、blocked_range2d を使用して反復空間を指定する、対応する並列行列乗算を示しています。

const size_t L = 150;
const size_t M = 225;
const size_t N = 300;

void SerialMatrixMultiply( float c[M][N], float a[M][L], float b[L][N] ) {
    for( size_t i=0; i<M; ++i ) {
        for( size_t j=0; j<N; ++j ) {
            float sum = 0;
            for( size_t k=0; k<L; ++k )
                sum += a[i][k]*b[k][j];
            c[i][j] = sum;
        }
    }
}
#include "tbb/parallel_for.h"
#include "tbb/blocked_range2d.h"

using namespace tbb;

const size_t L = 150;
const size_t M = 225;
const size_t N = 300;

class MatrixMultiplyBody2D {
    float (*my_a)[L];
    float (*my_b)[N];
    float (*my_c)[N];
public:
    void operator()( const blocked_range2d<size_t>& r ) const {
        float (*a)[L] = my_a;
        float (*b)[N] = my_b;
        float (*c)[N] = my_c;
        for( size_t i=r.rows().begin(); i!=r.rows().end(); ++i ){
            for( size_t j=r.cols().begin(); j!=r.cols().end(); ++j ) {
                float sum = 0;
                for( size_t k=0; k<L; ++k )
                    sum += a[i][k]*b[k][j];
                c[i][j] = sum;
            }
        }
    }
    MatrixMultiplyBody2D( float c[M][N], float a[M][L], float b[L][N] ) :
        my_a(a), my_b(b), my_c(c)
    {}
};

void ParallelMatrixMultiply(float c[M][N], float a[M][L], float b[L][N]){
    parallel_for( blocked_range2d<size_t>(0, M, 16, 0, N, 32),     
                  MatrixMultiplyBody2D(c,a,b) );
}

blocked_range2d は、シリアルバージョンの 2 つの最外ループを並列ループにします。parallel_for は、断片が 16x32 になるまで blocked_range2d を再帰的に分割して、各断片で MatrixMultiplyBody2D::operator() を呼び出します。

次の表は、このテンプレート・クラスのメンバーの詳細な情報を提供します。
メンバー 説明
row_range_type

blocked_range<RowValue>。つまり、行の値の型です。

col_range_type

blocked_range<ColValue>。つまり、列の値の型です。

blocked_range2d<RowValue,ColValue>( RowValue row_begin, RowValue row_end, typename row_range_type::size_type row_grainsize, ColValue col_begin, ColValue col_end, typename col_range_type::size_type col_grainsize )

効果: 値の 2 次元空間を表す blocked_range2d を構築します。空間は、行と列が指定された粒度の、半開直積 [row_begin, row_end) x [col_begin, col_end) です。

例: "blocked_range2d<char,int> r(’a’, ’z’+1, 3, 0, 10, 2);" 文は、形式 (i, j) のすべての値ペアを含む 2 次元の空間を構築します。ここで、i の範囲は 'a' から 'z' で粒度 3、j の範囲は 0 から 9 で粒度 2 です。

blocked_range2d<RowValue,ColValue>( RowValue row_begin, RowValue row_end, ColValue col_begin, ColValue col_end ) blocked_range2d(row_begin,row_end,1,col_begin,col_end,1) と同じ。
blocked_range2d<RowValue,ColValue> ( blocked_range2d& range, split )

基本分割コンストラクター。

要件: is_divisible() が true であること。

効果: range を 2 つのサブ範囲に分割します。新しく構築される blocked_range2d は、ほぼオリジナルの range の半分で、range は残りになるように更新されます。各サブ範囲の粒度はオリジナルの range の粒度と同じです。分割は行または列単位で行われます。範囲は選択した軸で分割され、分割が繰り返された後、サブ範囲の行と列はそれぞれの粒度の比率になります。例えば、row_grainsizecol_grainsize の 2 倍の場合、サブ範囲は列の 2 倍の行を持つようになります。

blocked_range2d<RowValue,ColValue> ( blocked_range2d& range, proportional_split proportion )

比例分割コンストラクター。

要件: is_divisible() が true であること。

効果: range を軸の 1 つで指定された proportion の 2 つのサブ範囲に分割します。分割する軸の選択は、基本分割コンストラクターと同じ方法で行われ、選択した軸に比例分割が行われます。2 番目の軸と各サブ範囲の粒度はオリジナルの range と同じです。

bool empty() const

効果: 範囲が空かどうかを決定します。

戻り値: rows().empty()||cols().empty()

bool is_divisible() const

効果: 範囲がサブ範囲に分割できるかどうかを決定します。

戻り値: rows().is_divisible()||cols().is_divisible()

const row_range_type& rows() const

戻り値: 値の空間の行を含む範囲。

const col_range_type& cols() const

戻り値: 値の空間の列を含む範囲。