OpenMP:决定它们是否是素数

OpenMP: decide if they are prime numbers

本文关键字:是否是 决定 OpenMP      更新时间:2023-10-16
请注意,这是一个基于思考的问题。给定的代码试图测试某个范围(10000000(以内的数字是否为素数。
bool test_prime(int x){
if (x == 0)
return false;
int lim = (int) sqrt((double) x);
for (int i = 2; i <= lim; i++) {
if (x % i == 0)
return false;
}
return true;
}
#pragma omp parallel for schedule(static)
for (int t = 0; t < nthreads; t++) {
tf(t, nthreads, xmax, isprime);
}

有两种类型的线程函数tf:

void thread_run_interleave(int t, int nthreads, int xmax, bool *isprime) {
for (int x = t; x <= xmax; x += nthreads) {
isprime[x] = test_prime(x);
}
}
void thread_run_chunk(int t, int nthreads, int xmax, bool *isprime) {
int npt = (xmax + nthreads - 1)/nthreads;
int xstart = npt*t;
int xlast = t == nthreads-1 ? xmax : xstart + npt - 1;
for (int x = xstart; x <= xlast; x++) {
isprime[x] = test_prime(x);
}
}

加速如下:

  1. 2个线程:交错1.04,块1.62
  2. 3个线程:交错1.93,块2.17
  3. 4个线程:交错1.92,块2.74
  4. 5个线程:交错3.53,块3.08
  5. 6个线程:交错1.93,块3.86

第一个问题要求解释thread_run_interleave的加速。(注意:回答此问题需要对CCD_ 3行为的思考。例如,它什么时候必须做很少的工作?(

  • 为什么使用2个线程没有加速
  • 为什么相对于线程数量,加速不是单调的?(提示:注意在4和6个线程处的行为。(

老实说,我不知道这是什么原因。我知道当输入x很小时,test_prime几乎不起作用,而对于大值,它会起很多作用。

根据您正在测试的硬件,您可能会在函数thread_run_interleave中遇到错误共享,因为您正在向isprime[x]写入,并且在每个线程中,值x可能相似(取决于这些线程在cpu上的调度方式(。这可以解释使用更多线程时速度减慢的原因。

这可以通过在每个线程中处理一小块锥形数字来解决。假设您的缓存线是64B宽,那么您将在每个线程中处理64/sizeof(bool(连续的数字,然后将x移动(64/sizeof(bool,(*nthreads(假设isprime是一个bool数组(。