C++14後のParallelism TSで提案されている並列アルゴリズムについての考察。
N3850 Working Draft, Technical Specification for C++ Extensions for Parallelism
この提案にはshuffle()
の並列版は予定されていないのですが、そのアルゴリズムを入れることは可能なのかと。Boost.Computeを見てみたら、random_shuffle()
の実装が、以下のようになっていました。
template<class Iterator> inline void random_shuffle(Iterator first, Iterator last, command_queue &queue = system::default_queue()) { typedef typename std::iterator_traits<Iterator>::value_type value_type; size_t count = detail::iterator_range_size(first, last); if(count == 0){ return; } // generate shuffled indices on the host std::vector<cl_uint> random_indices(count); boost::iota(random_indices, 0); std::random_shuffle(random_indices.begin(), random_indices.end()); // copy random indices to the device const context &context = queue.get_context(); vector<cl_uint> indices(count, context); ::boost::compute::copy(random_indices.begin(), random_indices.end(), indices.begin(), queue); // make a copy of the values on the device vector<value_type> tmp(count, context); ::boost::compute::copy(first, last, tmp.begin(), queue); // write values to their new locations ::boost::compute::scatter(tmp.begin(), tmp.end(), indices.begin(), first, queue); }
https://github.com/kylelutz/compute/blob/master/include/boost/compute/algorithm/random_shuffle.hpp
以下のような作りになっていました。
- CPU(メインスレッド)でランダムに並んだインデックスを作っておく
- デバイス(GPU)で、事前に計算しておいたランダムなインデックスに、並列に並び替えを行う。
なので、乱数生成器は並列に特化したものじゃなくてもよさそうなので、従来のmt19937
とかをそのまま並列シャッフルに使えそうです。
では先日のVexCLの並列乱数アルゴリズムは何に使うかというと、おそらくランダムな行列を作るのに使うのでしょう。