【问题标题】:OpenMP: decide if they are prime numbersOpenMP:确定它们是否是素数
【发布时间】:2019-11-05 09:40:34
【问题描述】:

请注意,这是一个基于思考的问题。 给定的代码尝试测试某个范围(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, 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 的加速。 (注:回答这个问题需要 思考test_prime 的行为。例如,它什么时候必须做很少的工作?)

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

老实说,我不知道这是什么原因。我知道test_prime 在输入 x 很小的情况下几乎没有什么作用,而对于较大的值却有很多作用。

【问题讨论】:

  • 请为您的问题创建一个minimal reproducible example,并添加详细的硬件描述以及有关如何编译代码的信息。
  • 好吧,我只是想出了 2 线程的原因。线程 0 获得所有偶数,因此它们都不是素数,它们可以被 2 整除并快速退出 test_prime。另一方面,线程 1 必须测试更长的时间,因为它具有所有质数。这种工作负载不平衡导致 1 个线程运行大部分工作,因此在速度方面接近串行。
  • @Zulan 这实际上是一个书面作业问题,所以没有代码。
  • @KcAble 你可以自己写答案并接受它。
  • 这里有几个 Q 和 As 来解决这个问题中提出的问题。例如,请参阅stackoverflow.com/questions/15463046

标签: c++ multithreading openmp


【解决方案1】:

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

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

【讨论】:

    猜你喜欢
    • 2011-08-14
    • 1970-01-01
    • 1970-01-01
    • 2016-09-27
    • 1970-01-01
    • 1970-01-01
    • 2011-06-09
    • 1970-01-01
    相关资源
    最近更新 更多