OpenMP:决定它们是否是素数
OpenMP: decide if they are prime numbers
请注意,这是一个基于思考的问题。给定的代码试图测试某个范围(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);
}
}
加速如下:
- 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
的加速。(注意:回答此问题需要对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数组(。
相关文章:
- C++LDAP检查用户是否是特定组的成员
- 检查某些类型是否是模板类 std::optional 的实例化
- 将错误返回给调用方而不是立即在 C++ 中抛出错误是否是一种好的做法
- 如何检查模板专用化是否是基本模板的子类?
- 如何检查变量是否是C++中的地图?
- C++ Chrono 确定一天是否是周末?
- 将相同共享指针的副本存储在不同的向量中是否是一种好的做法?
- 使用类在C++中存储和列出变量/方法是否是一种好的做法
- 代码在 CodeSignal 中工作不正确。不确定这是否是我的代码缺陷
- 如果 C 函数仍然可以间接执行(通过回调函数),那么将它声明为静态函数是否是一种不好的做法?
- MFC 中的窗口消息管理:添加基类调用是否是强制性的?
- 检查 n2 是否是 n1 的倍数后结果错误,但根本没有错误
- C ++:检查它是否是类中的数字
- 传递给放置 new 的指针是否是指向其对象表示形式的非 UB 指针?
- 使用 SET(C++) 检查两个给定字符串是否是字谜时出现运行时错误
- 从 std::string 到 std::array<char,size> 的 memcopy 额外数据是否是一种未定义的行为?
- 有没有办法检查发送到变量的值是否是正确的类型,而它已经在该变量下?
- 如何检查一个模板是否是另一个模板的类成员
- 有没有办法检查用户输入是否是数字?
- OpenMP:决定它们是否是素数