7

a = a + b + c を書くより効率的な方法があるかどうか疑問に思っていましたか?

 thrust::transform(b.begin(), b.end(), c.begin(), b.begin(), thrust::plus<int>());
 thrust::transform(a.begin(), a.end(), b.begin(), a.begin(), thrust::plus<int>());

これは機能しますが、コードを 1 行だけ使用して同じ効果を得る方法はありますか? 例で saxpy の実装を見ましたが、これは 2 つのベクトルと定数値を使用しています。


これはより効率的ですか?

struct arbitrary_functor
{
    template <typename Tuple>
    __host__ __device__
    void operator()(Tuple t)
    {
        // D[i] = A[i] + B[i] + C[i];
        thrust::get<3>(t) = thrust::get<0>(t) + thrust::get<1>(t) + thrust::get<2>(t);
    }
};


int main(){

     // allocate storage
    thrust::host_vector<int> A;
    thrust::host_vector<int> B;
    thrust::host_vector<int> C;

    // initialize input vectors
    A.push_back(10);
    B.push_back(10);
    C.push_back(10);

    // apply the transformation
    thrust::for_each(thrust::make_zip_iterator(thrust::make_tuple(A.begin(), B.begin(), C.begin(), A.begin())),
                     thrust::make_zip_iterator(thrust::make_tuple(A.end(),   B.end(),   C.end(),   A.end())),
                     arbitrary_functor());

    // print the output
       std::cout << A[0] << std::endl;

    return 0;
}
4

1 に答える 1

8

a = a + b + c演算強度が低い (4 つのメモリ操作ごとに 2 つの算術演算のみ) ため、計算はメモリ帯域幅の制約を受けることになります。提案されたソリューションの効率を比較するには、帯域幅の需要を測定する必要があります。

最初のソリューションのへの呼び出しtransformごとに、 への呼び出しごとに 2 つのロードと 1 つのストアが必要plusです。transformしたがって、各呼び出しのコストを としてモデル化できます3N。ここNで、 はベクトルab、およびのサイズですc。の呼び出しが 2 回transformあるため、このソリューションのコストは です6N

同じ方法で、2 番目のソリューションのコストをモデル化できます。の各呼び出しにarbitrary_functorは、3 つのロードと 1 つのストアが必要です。したがって、このソリューションのコスト モデルは になります。これは、ソリューションが2 回呼び出すよりも効率的で4Nあることを意味します。が大きい場合、2 番目のソリューションは最初のソリューションよりも高速に実行されます。for_eachtransformN6N/4N = 1.5x

もちろん、 を2 回別々に呼び出すのを避けるために、常に同様の方法で とzip_iterator組み合わせることができます。transformtransform

于 2011-09-25T03:59:45.040 に答える