我想使用OpenMP并行填充直方图。我想出了两种使用C / C ++中的OpenMP进行此操作的方法。
第一种方法为每个线程proccess_data_v1创建一个私有直方图变量hist_private,将其填充成小节,然后将私有直方图求和成hist一个critical部分中的共享直方图。
第二种方法proccess_data_v2制作一个共享直方图数组,其数组大小等于线程数,并行填充此数组,然后并行求和该共享直方图hist。
第二种方法对我来说似乎更好,因为它避免了关键部分,并且并行地对直方图求和。但是,它需要知道线程数并调用omp_get_thread_num()。我通常会尝试避免这种情况。有没有更好的方法来执行第二种方法而不引用线程号并使用大小等于线程数的共享数组?
void proccess_data_v1(float *data, int *hist, const int n, const int nbins, float max) {
#pragma omp parallel
{
int *hist_private = new int[nbins];
for(int i=0; i<nbins; i++) hist_private[i] = 0;
#pragma omp for nowait
for(int i=0; i<n; i++) {
float x = reconstruct_data(data[i]);
fill_hist(hist_private, nbins, max, x);
}
#pragma omp critical
{
for(int i=0; i<nbins; i++) {
hist[i] += hist_private[i];
}
}
delete[] hist_private;
}
}
void proccess_data_v2(float *data, int *hist, const int n, const int nbins, float max) {
const int nthreads = 8;
omp_set_num_threads(nthreads);
int *hista = new int[nbins*nthreads];
#pragma omp parallel
{
const int ithread = omp_get_thread_num();
for(int i=0; i<nbins; i++) hista[nbins*ithread+i] = 0;
#pragma omp for
for(int i=0; i<n; i++) {
float x = reconstruct_data(data[i]);
fill_hist(&hista[nbins*ithread], nbins, max, x);
}
#pragma omp for
for(int i=0; i<nbins; i++) {
for(int t=0; t<nthreads; t++) {
hist[i] += hista[nbins*t + i];
}
}
}
delete[] hista;
}
慕妹3242003
慕丝7291255
POPMUISE