OpenMP:确定它们是否为质数

请注意,这是一个基于思考的问题。 给定的代码尝试测试不超过一定范围(10,000,000)的数字是否为质数。

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,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的加速。 (注意:回答此问题需要 考虑test_prime的行为。例如,什么时候它必须做很少的工作?)

  • 为什么不使用2个线程加速?
  • 为什么关于线程数的加速不是单调的? (提示:注意 4和6个线程的行为。)

老实说,我不知道原因。我知道在输入test_prime很小的情况下x的工作量很少,而对于大的值它却做了很多工作。

whitegjhh 回答:OpenMP:确定它们是否为质数

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

可以通过在每个线程中处理一小段切语数字来解决此问题。 假设您的缓存行宽为64B,那么您将在每个线程中处理64 / sizeof(bool)个连续数字,然后将x移动(64 / sizeof(bool))* nthreads(假设isprime为一堆布尔值。

本文链接:https://www.f2er.com/3160776.html

大家都在问