C 有没有办法让这个程序更快?

C 有没有办法让这个程序更快?,c,C,有没有办法让这个程序以10000000个数字的速度运行超过3.8秒?该代码检查随机生成的数字,并对其中的素数进行计数和求和。im使用4个线程,每个线程在一个核心上运行。我很确定有一种比这个更快的算法来检查素数,但我找不到 #include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <math.h> #include <semaphore.h> long su

有没有办法让这个程序以10000000个数字的速度运行超过3.8秒?该代码检查随机生成的数字,并对其中的素数进行计数和求和。im使用4个线程,每个线程在一个核心上运行。我很确定有一种比这个更快的算法来检查素数,但我找不到

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <math.h>
#include <semaphore.h>

long sum=0,count=0;
pthread_mutex_t lock;
int numOfRandomNumbers;


int isPrime(int num)
{
int i;

if(num==2||num==3) 
return 1;

if(num%2==0||num%3==0)
return 0;


if((num-1)%6!=0&&((num+1)%6)!=0||((num*num)-1)%8!=0)return 0;


for (i = 5;i*i<=num;i+=6)
{
if (num%i == 0||num%(i+2)==0)return 0;
        
}
return 1;
}

void* prime(void * arg)
{  
int size=*(int*) arg;
int random;
for(int i=0;i<size;i++)
{   
random=rand();
if(isPrime(random))
{ 
pthread_mutex_lock(&lock);
sum+=random;
count+=1;
pthread_mutex_unlock(&lock);
}
}
}
int main(int argc, char *argv[])
{

if(pthread_mutex_init(&lock,NULL)!=0)
{
printf("mutix init failed\n"); return 0;
}
if(argc != 3) 
{
printf("Too few arguments ");
printf("USAGE: ./primeCalc <prime pivot> <num of random numbers>");
exit(0);
}
pthread_t tids[4];

int randomPivot = atoi(argv[1]);
numOfRandomNumbers = atoi(argv[2]);
int random = rand();
srand(randomPivot);

long size1 =numOfRandomNumbers/4;
long size2=(2*numOfRandomNumbers/4)-numOfRandomNumbers/4;
long size3=(3*numOfRandomNumbers/4)-(2*numOfRandomNumbers/4);
long size4=numOfRandomNumbers-(3*numOfRandomNumbers/4);

pthread_create(&tids[0], NULL, prime, &size1);
pthread_create(&tids[1], NULL, prime, &size2);
pthread_create(&tids[2], NULL, prime, &size3);
pthread_create(&tids[3], NULL, prime, &size4);

pthread_join(tids[0], NULL);
pthread_join(tids[1], NULL);
pthread_join(tids[2], NULL);
pthread_join(tids[3], NULL);

   
pthread_mutex_destroy(&lock);
//keep the out format as this!!
printf("%ld,%ld\n",sum,count);

exit(0);
}
#包括
#包括
#包括
#包括
#包括
长和=0,计数=0;
pthread_mutex_t lock;
整数;
intisprime(intnum)
{
int i;
如果(num==2 | | num==3)
返回1;
如果(数值%2==0 | |数值%3==0)
返回0;
如果((num-1)%6!=0&((num+1)%6)!=0 | |((num*num)-1)%8!=0),则返回0;

对于(i=5;i*i,我想到了两种算法:

Eratosthenes和OpenMP

我不是说一个“纯”的筛选实现。但基本思想是,较小的素数有助于找到较大的素数。不需要除以每个不均匀数

这就是你尝试的
i+=6
技巧。这只适用于较低的区域。通过一系列找到的素数,可能的除数被集中。无论你是将它们用作筛子还是用于试除法,都是次要的(分段筛子比除法快)

对于随机素数候选者,这一点不太明显。但是,对于高达20亿(RAND_MAX)的大量候选者来说,高达44000的素数数组就足够了。与3.8秒相比,在短时间内完成就足够了

(也有数学算法,也使用一些表格-看看有多快,例如,
因子
效用)

关于并发问题:

所有这些线程(包括计数)都可以通过一条(半)OpenMP线来处理。不仅更容易,而且速度更快,甚至可能在您修复瓶颈之后

因此,这将是一个可用于并行编程的现成算法。



伟大的XY笑话:你要求快速素数算法,但问题是线程被中断。

首先,你有太多的额外检查。
num==2
num==3
在你插入的一组数字中不太可能,所以最好先检查number是否停止为每个增量锁定互斥锁。修改代码因此,每个线程通过将其放入一个传递给它的结构中来完成自己的计数并报告一次(将它应该测试的“大小”也放入该结构中,这样就通过指针传递了一个结构,其中包含“大小”和返回计数的空间)然后在主线程中添加计数。您根本不需要互斥。如果您的代码已经在运行,并且您只是在寻求性能改进,那么将此问题发布到堆栈溢出上似乎比发布在堆栈溢出上更合适,除非您的问题的焦点不应该是您的代码,而应该是使用哪个算法。否te不能保证
rand
是线程安全的。这适用于POSIX和ISO C。即使在您的平台上是线程安全的,它也可能在您生成新随机数时使用线程同步。因此,出于性能原因,您可能应该使用支持独立基因的随机数生成器在没有线程同步的情况下,几个线程上随机数的比率。不幸的是,ISO C没有提供这样的随机数生成器(不确定POSIX)。@AndreasWenzel,
rand_r
AFAIK应该是POSIX和线程安全的(tread safety自然假定对每个种子变量的非并发访问)对于那些接受glibc扩展的人,还有
random\r