ここでは、隣接する対角隣接を見つける基本テストを行い、4x4単位行列を使用して結果を記録するアルゴリズムがあります。これには、OMPまたは並列コンピューティングの使用は含まれません。しかしこれは、使用するのに十分シンプルなMxN行列の汎用クラステンプレートです。内容をベクトルのベクトルに格納する代わりに、私は単一の1Dベクトルにデータを平坦化し、テンプレートのインスタンス化時にすでにメモリの量が保存されています。関数テンプレートを使用して、インデックス(M,N)
または(x,y)
を返す行列内の要素と、結果が真または偽であるかどうかを比較しています。ここではx-yインデックス&の関係を含む構造体を使用します。隣人をチェックする経験則は、最後の列&の行列の最後の行を見ることを避ける。なぜなら、父親は右にも奥にも要素がないからである。これは主関数内に見ることができる。これは、クラスを適用しようとする可能性のある場所に、&関数をOMPライブラリに組み込むのに役立ちます。
template<unsigned Col, unsigned Row>
class Matrix2D {
public:
const unsigned col_size = Col;
const unsigned row_size = Row;
const unsigned stride_ = col_size;
const unsigned matrix_size = col_size * row_size;
private:
std::vector<int> data_;
public:
Matrix2D() {
data_.resize(matrix_size);
}
void addElement(unsigned x, unsigned y, int val) {
data_[(x * col_size + y)] = val;
}
/*int getElement(unsigned x, unsigned y) {
int value = data_[(x * col_size + y)];
return value;
}*/
int getElement(unsigned idx) {
return data_[idx];
}
};
struct Neighbor {
unsigned indexCol;
unsigned indexRow;
bool notSame;
};
template<unsigned Col, unsigned Row>
void compareMatrixDiagonals(Matrix2D<Col, Row>& mat, Neighbor& n, unsigned colIdx, unsigned rowIdx);
int main() {
Matrix2D<4, 4> mat4x4;
mat4x4.addElement(0, 0, 1);
mat4x4.addElement(0, 1, 0);
mat4x4.addElement(0, 2, 0);
mat4x4.addElement(0, 3, 0);
mat4x4.addElement(1, 0, 0);
mat4x4.addElement(1, 1, 1);
mat4x4.addElement(1, 2, 0);
mat4x4.addElement(1, 3, 0);
mat4x4.addElement(2, 0, 0);
mat4x4.addElement(2, 1, 0);
mat4x4.addElement(2, 2, 1);
mat4x4.addElement(2, 3, 0);
mat4x4.addElement(3, 0, 0);
mat4x4.addElement(3, 1, 0);
mat4x4.addElement(3, 2, 0);
mat4x4.addElement(3, 3, 1);
unsigned idx = 0;
for (unsigned i = 0; i < mat4x4.matrix_size; i++) {
std::cout << mat4x4.getElement(i) << " ";
idx++;
if (idx == 4) {
std::cout << "\n";
idx = 0;
}
}
std::cout << "\n";
unsigned colIdx = 0;
unsigned rowIdx = 0;
std::vector<Neighbor> neighbors;
Neighbor n;
// If we are in the last col or row we can ignore
// (0,3),(1,3),(2,3),(3,3),(3,0),(3,1),(3,2), {*(3,3)* already excluded}
// This is with a 4x4 matrix: we can substitute and use LastCol - LastRow
// for any size MxN Matrix.
const unsigned LastCol = mat4x4.col_size - 1;
const unsigned LastRow = mat4x4.row_size - 1;
for (unsigned i = 0; i < LastCol; i++) {
for (unsigned j = 0; j < LastRow; j++) {
compareMatrixDiagonals(mat4x4, n, i, j);
neighbors.push_back(n);
}
}
for (unsigned i = 0; i < neighbors.size(); i++) {
std::cout << "(" << neighbors[i].indexCol
<< "," << neighbors[i].indexRow
<< ") " << neighbors[i].notSame
<< "\n";
}
std::cout << "\nPress any key & enter to quit." << std::endl;
char c;
std::cin >> c;
return 0;
}
template<unsigned Col, unsigned Row>
void compareMatrixDiagonals(Matrix2D<Col, Row>& mat, Neighbor& N, unsigned colIdx, unsigned rowIdx) {
unsigned firstIdx = (colIdx * mat.col_size + rowIdx);
unsigned nextIdx = ((colIdx + 1) * mat.col_size + (rowIdx + 1));
if (mat.getElement(firstIdx) != mat.getElement(nextIdx)) {
N.indexCol = colIdx;
N.indexRow = rowIdx;
N.notSame = true;
} else {
N.indexCol = colIdx;
N.indexRow = rowIdx;
N.notSame = false;
}
}
スレッドローカルベクトルにペア(x、y)または(y、x)を格納し、内部ループの終了後にRow/ColWiseDiscontinuityに追加することについて考えましたか?この方法で少量の追加ストレージしか使用せず、Row/ColWiseDiscontinuityへの挿入はパフォーマンスに大きな影響を与えることなく順番に実行できます(私は不連続性がまばらにしか起こらないと仮定しています) –
'2Dベクトルマトリックス'' 1D vector'にストライド値を使用して行に何個の列をマークするか? –
'TempX1'、' TempX2'を削除し、 'Matrix2D'から直接データを使うことができます。うまくいけば、外側ループを並列化することができます。しかし、 'Matrix2D'がキャッシュに収まらない場合は、メモリー帯域幅に縛られている可能性があります。 – geza