環境
- C++11 (C++14, 17, 20 で実現可能なら他のバージョンでも可)
- Visual Studio 2017
質問内容
std::vector の配列の各要素を関数に渡して、ある処理を行って要素の値を更新するとします。
現在は以下のように順番に各要素に処理を行っていますが、1つの処理の計算量が重く、独立して行える処理のため、マルチスレッドで行いたいと思いました。
cpp
1for(auto &v: vec) 2 some_process(v);
そのため、std::vector の配列をスレッド数分に分割して関数に渡して処理したいと思ったのですが、C++ で Python のように「配列の一部の参照を作成して、関数に渡す」ということはできるのでしょうか。
現在は指定範囲のイテレータを渡すようにしていますが、よりよい方法があれば、ご教示いただけないでしょうか。
cpp
1#include <algorithm> 2#include <cmath> 3#include <iostream> 4#include <numeric> 5#include <thread> 6#include <vector> 7 8class SomeClass 9{ 10 public: 11 void process( 12 std::vector<int>::iterator &begein, 13 std::vector<int>::iterator &end, 14 int mul) const 15 { 16 // vec の各要素になにかの処理、以下は例であり、実際は重たい処理になります。 17 std::for_each( 18 begein, end, [mul](int &v) { v = v * mul; }); 19 } 20}; 21 22 23int main() 24{ 25 SomeClass obj; 26 27 // 初期化 28 std::vector<int> vec(50); 29 // vec = {1, 2, ..., 50} 30 std::iota(vec.begin(), vec.end(), 1); 31 std::for_each( 32 vec.begin(), vec.end(), [](int &v) { std::cout << v << std::endl; }); 33 34 // マルチスレッドで処理 35 const int num_threads = 5; // スレッド数 36 std::vector<std::thread> threads; 37 38 // スレッドを作成する。 39 for (int i = 0; i < num_threads; ++i) { 40 auto begin = vec.begin() + i * 10; 41 auto end = begin + 10; 42 43 threads.push_back(std::thread( 44 &SomeClass::process, &obj, std::ref(begin), std::ref(end), i)); 45 } 46 47 // スレッドの終了待機 48 for (std::thread &t : threads) 49 t.join(); 50 51 // vec = {1*0, 2*0, ..., 9*0, 10*1, 11*1, ...} 52 std::for_each( 53 vec.begin(), vec.end(), [](int &v) { std::cout << v << std::endl; }); 54}
聞きたいこと
- std::vector の配列の一部の参照を作る方法について。
- 配列の各要素を(同じ要素にアクセスすることはないとはいえ)別々のスレッドから変更することに問題はないかどうか。
※ 上記の配列をスレッド数分分割して、スレッドごとに処理するというのは、とりあえず思いついた方法なので、それ以外の方法で高速化可能なら方法はなんでもいいです。
すみませんが、よろしくおねがいします。

回答3件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/03/19 16:05 編集
2019/03/19 16:11
2019/03/19 16:20
2019/03/19 16:23
2019/03/20 02:51