ホグワイルドを実装しようとしています!線形 SVMアルゴリズムですが、実装で誤った共有の問題が発生しています。
私のコードは以下にありますが、背景は、どのサンプルがテストに失敗し、そのベクトルのセットによって与えられたものを作成および更新するかを計算しようとしているということです。ホグワイルド!(私が理解している限り)同じメモリで完全に非同期に更新するだけです。これにより、不適切な時間の更新により、数学的な意味で「ノイズ」が発生します。
残念ながら、これらの非同期更新を行おうとすると、L1 キャッシュが無効になり、再取得する必要があります。以下は私のコードです。
非同期を失うことなく、この誤った共有を修正する良い方法はありますか? (私はコンピューター科学者というより数学者です)。これは、異なる最適化レベルを使用するとこれを修正できることを示しています。
void update(size_t epoch, const double *X_data, const int *X_indices,
const int *X_indptr, const int *Y, double *W,
double reg, double step_size, size_t nodes,
size_t X_height, size_t X_width) {
size_t i, j;
double step = step_size/(1 + epoch);
double c;
#pragma omp parallel shared(W, X_data, X_indices, X_indptr, Y) private(i, j, c)
{
#pragma for schedule(static)
for (i=0;i<X_height;i++) {
c = 0.0;
for (j=X_indptr[i];j<X_indptr[i+1];j++)
c += X_data[j]*W[X_indices[j]]; // Scaled to discount the MPI scaling
if (Y[i]*c > 1)
continue;
for (j=X_indptr[i];j<X_indptr[i+1];j++)
W[X_indices[j]] += step*Y[i]*X_data[j]/(X_height*nodes);
} // END FOR OMP PARALLELIZED
#pragma for schedule(static) // Might not do much
for (i=0;i<X_width;i++) // (1 - self.reg*step)*self.W/self.nodes +
W[i] *= (1 - reg*step)/nodes;
}
}