- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
这个问题的目标是能够得到第 2.000.000 个素数,并能够分辨第 2.000.000 个素数是哪个。
我们从这段代码开始:
#include <stdlib.h>
#include <stdio.h>
#define N 2000000
int p[N];
main(int na,char* arg[])
{
int i;
int pp,num;
printf("Number of primes to find: %d\n",N);
p[0] = 2;
p[1] = 3;
pp = 2;
num = 5;
while (pp < N)
{
for (i=1; p[i]*p[i] <= num ;i++)
if (num % p[i] == 0) break;
if (p[i]*p[i] > num) p[pp++]=num;
num += 2;
}
printf("The %d prime is: %d\n",N,p[N-1]);
exit(0);
}
现在我们被要求通过 pragma omp 使这个进程线程化。这是我到目前为止所做的:
#include <stdlib.h>
#include <stdio.h>
#define N 2000000
#define D 1415
int p[N];
main(int na,char* arg[])
{
int i,j;
int pp,num;
printf("Number of primes to find: %d\n",N);
p[0] = 2;
p[1] = 3;
pp = 2;
num = 5;
while (pp < D)
{
for (i=1; p[i]*p[i] <= num ;i++)
if (num % p[i] == 0) break;
if (p[i]*p[i] > num) p[pp++]=num;
num += 2;
}
int success = 0;
int t_num;
int temp_num = num;
int total = pp;
#pragma omp parallel num_threads(4) private(j, t_num, num, success)
{
t_num = omp_get_thread_num();
num = temp_num + t_num*2;
#pragma omp for ordered schedule(static,4)
for(pp=D; pp<N; pp++) {
success = 0;
while(success==0) {
for (i=1; p[i]*p[i] <= num;i++) {
if (num % p[i] == 0) break;
}
if (p[i]*p[i] > num) {
p[pp] = num;
success=1;
}
num+=8;
}
}
}
//sort(p, 0, N);
printf("El %d primer es: %d\n",N,p[N-1]);
exit(0);
}
现在让我解释一下我的“部分”解决方案,以及我的问题。
前D个素数是用序列码得到的,所以现在我可以检查大量数字的整除性。
每个线程都运行素数对角线,因此线程之间没有依赖关系,也不需要同步。但是,这种方法存在以下问题:
问题/困境是:
我如何才能知道第 2.000.000 个素数何时生成?
提示:有人告诉我,我应该做一批(比方说)10.000 个素数候选者。然后当我不知道的事情发生时,我会知道最后一批 10.000 个候选者包含第 2.000.000 个素数,我可以用快速排序对其进行排序。
我希望我说清楚,这真的是一项艰巨的运动,我只是连续几天不停地尝试。
最佳答案
如果您只需要 2000000 个素数,您可以维护一个 ~4.1MB 大小的位数组并为每个找到的素数翻转位。不需要排序。通过实现仅赔率表示方案将您的位数组大小减半。
使用Sieve of Eratosthenes ,在段中,大小与 sqrt(top_value_of_range)
成比例(或类似的东西 - 目标是在每个段上执行大约相同数量的工作)。对于 n=2000000
,n*(log n + log(log n)) == 34366806
和 prime[771]^2 == 34421689
(从 0 开始),因此,预先计算前 771 个奇素数。
每个 worker 也可以计数,因为它翻转位,所以当它们全部完成时,您将知道每个范围的计数,并且只需要扫描包含第 200 万个素数的一个范围,在结束,找到素数。或者让每个工作人员根据其范围维护自己的位数组——您只需要保留一个,而可以丢弃其他的。
计算埃拉托色尼筛法的伪代码是:
Input: an integer n > 1
Let A be an array of bool values, indexed by integers 3, 5, ... upto n,
initially all set to true.
count := floor( (n-1)/2 )
for i = 3, 5, 7, ..., while i^2 ≤ n:
if A[i] is true:
for j = i^2, i^2 + 2i, i^2 + 4i, ..., while j ≤ n:
if A[j] is true:
A[j] := false
count := count - 1
Now all 'i's such that A[i] is true are prime,
and 'count' is the total count of odd primes found.
关于c - 使用#pragma omp 进行硬并行化以找到第 N 个素数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13520262/
好的,我希望以前没有问过这个问题,因为在搜索中很难找到。 我查看了 F95 手册,但仍然觉得这很模糊: For the simple case of: DO i=0,99 END DO 我正
这两者有什么区别? [一] #pragma omp parallel { #pragma omp for for(int i = 1; i < 100; ++i) {
这两者有什么区别? [一] #pragma omp parallel { #pragma omp for for(int i = 1; i < 100; ++i) {
我有这段代码: #include #include int main(){ int i,j = 0 ; int tid; # pragma omp parallel pri
刚开始接触OPENMP,想用它来求解波动方程,串口代码在这里: #include #include #include #include #define GRID_SZ 3000 #define
我对 omp single 感到困惑和 omp task指令。我已经阅读了几个使用它们的例子。以下示例显示如何使用任务构造来处理链表的元素。 1 #pragma omp parallel 2 {
我试图了解 omp ordered 和 omp critical 之间的区别。他们都没有相同的语义吗?每个线程中编写的代码都被串行执行,当一个线程处于有序/关键 block 中时,其他线程等待。我看不
是否可以在 omp 并行 block 之外使用 omp pragma,如 critical、single、master 或 barrier?我有一个函数可以从 OMP 并行 block 调用,也可以不
我想测试 #pragma omp parallel for 和 #pragma omp simd 一个简单的矩阵加法程序。当我分别使用它们时,我没有收到任何错误,而且看起来还不错。但是,我想测试使用它
考虑: void saxpy_worksharing(float* x, float* y, float a, int N) { #pragma omp parallel for
我试图了解 #pragma omp critical 之间的确切区别和 #pragma omp single在 OpenMP 中: Microsoft 对这些的定义是: Single:让您指定应在其上
在带有 openMP 的 C++ 中,两者之间有什么区别吗 #pragma omp parallel for for(int i=0; i
我正在处理一些事情,试图让孤立工作发挥作用,并通过减少 #pragma omp parallel 的调用来减少开销。我正在尝试的是这样的: #pragma omp parallel default(n
在我学习 OpenMP 的过程中,我遇到了一个示例,其中的主要内容如下所示: int main(){ #pragma omp parallel #pragma omp sing
我是 OpenMP 的新手,我一直在尝试运行一个使用 OpenMP 添加两个数组的程序。在 OpenMP 教程中,我了解到,在 for 循环上使用 OpenMP 时,我们需要使用 #pragma om
我正在阅读 Peter S. Pacheco 的《并行编程简介》一书。在第 5.6.2 节中,它对减少 fork/join 开销进行了有趣的讨论。 考虑奇偶转置排序算法: for(phase=0; p
之间有什么区别: #pragma omp for {for_loop} 和 #pragma omp parallel for {for_loop} 最佳答案 #pragma omp par
在 OpenMP 中 #pragma omp master 中的任何代码指令由单个线程(主线程)执行,在区域末尾没有隐含的屏障。 (见 section on MASTER directive in t
如果我明白 aligned omp simd的条款构造,它指的是整个数组的对齐方式。 它如何用于多维数组?认为 ni = 131; nj = 137; nk = 127 !allocates arr
我有一个问题:我必须使用 OMP 并行化这段代码。 存在数据依赖问题,不知道如何解决。有什么建议么? for (n = 2; n < N+1; n++) { dz = *(dynamic_d +
我是一名优秀的程序员,十分优秀!