请注意,这是一个基于思考的问题。 给定的代码尝试测试不超过一定范围(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);
}
}
提速如下:
- 2个线程:交织1.04,块1.62
- 3个线程:交织1.93,块2.17
- 4个线程:交织1.92,块2.74
- 5个线程:交织3.53,块3.08
- 6个线程:交织1.93,块3.86
第一个问题要求解释thread_run_interleave
的加速。 (注意:回答此问题需要
考虑test_prime
的行为。例如,什么时候它必须做很少的工作?)
- 为什么不使用2个线程加速?
- 为什么关于线程数的加速不是单调的? (提示:注意 4和6个线程的行为。)
老实说,我不知道原因。我知道在输入test_prime
很小的情况下x
的工作量很少,而对于大的值它却做了很多工作。