3

ギャング。まず、問題とアプローチの概要を説明します。

画像と各画像のピクセル位置を含むリスト(リストのリスト)があります。その画像のリストからランダムにn個のアイテムを選択し、画像ごとにk個のランダムなピクセル位置を反復処理します。これを並行してやりたいです。処理されたピクセルごとに、リストから削除したいと思います。

私のアプローチは、画像とピクセルリストをすべてのスレッドに分散することです。したがって、各スレッドには独自の画像リストとピクセル位置のリストがありますが、2つのスレッドが同じ画像を同時に処理することはありません。これらをベクトルに格納します。

したがって、コードが次のようになっているとしましょう。

struct MyObject
{
  // Image index on disk
  int imageIndex_;
  // List of x,y locations
  std::list< Point > pixels_;
};

std::vector< std::list < MyObject > > mainList(NUM_THREADS);

次に、mainList[0]ID 0のスレッドで処理される画像が含まれます。次の方法でスレッドを起動します。#pragma omp parallel num_threads(numThreads_)次に、スレッドの画像リストからランダムに画像をサンプリングする同じコードを実行します。

問題は、ピクセルが処理され、スレッドがピクセルリストからピクセルを消去するときに、たとえばmainList[0].begin()->pixels_.erase(someIter)、アサーションを取得することがあることです。削除演算子までトレースします。

std :: listへの書き込みはスレッドセーフではないことは知っていますが、メインリストの各リストに1つのスレッドのみがアクセスする、リストのリストに対しては安全であると確信していました。限られたコードを提供したことは知っていますが、問題は、各スレッドが一度に1つのリストにしかアクセスできず、リストがスレッド間で共有されていない場合に、リストのリスト(またはリストのベクトル)から並行して削除することになります。

ここで何が欠けていますか?リストのリストのベクトルから並行して削除することはできませんか?

4

1 に答える 1

1

あなたは私が本当の問題を推測するには少なすぎる情報を提供しました、ここにいくつかの考えがあります:

無効化されたイテレータにアクセスしているようです(つまり、1つの要素を2回削除します)。これは、競合状態、または実際にアイテムを複数回削除しようとするコードのバグが原因である可能性があります。たとえば、生成した乱数が一意であることを確認しますか?インデックスが有効であることを確認するために、各要素が削除された後、生成された乱数にモジュロ演算子を適用しますか?

最初に確認するのは、OpenMPを無効にしてプログラムを実行することです。次に、競合状態が原因でアサーションが失敗するのか、別のバグが原因でアサーションが失敗するのかを判断できます。

関係のないメモstd::vectorについては、の代わりに使用することをお勧めしますstd::list。コンテナ内のランダム要素にアクセスしておりstd::vector、ランダムアクセス用に最適化されています。

于 2010-10-14T20:12:14.543 に答える