我写了一个计算素数的程序。首先我编写了“常规”代码并且它工作得很好,但我想让计算更快,所以我决定将计算分成两个同时计算的线程。两个线程都与互斥锁同步,但它比我的单线程版本慢大约4-5倍。这是代码:
#include <pthread.h>
#include <stdio.h>
unsigned long isqrt(unsigned long x) //function to calculate sqrt of int, not mine
{
register unsigned long op, res, one;
op = x;
res = 0;
one = 1 << 30;
while (one > op) one >>= 2;
while (one != 0)
{
if (op >= res + one)
{
op -= res + one;
res += one << 1;
}
res >>= 1;
one >>= 2;
}
return res;
}
static unsigned long long n;
pthread_mutex_t lock;
pthread_mutex_t lock1;
void *threadFunc(void *arg)
{
unsigned long long num, x, a, b = 0, sqrtNum;
for(num = 3; num <= n; num += 4)
{
a = 0;
sqrtNum = isqrt(num);
for(x = 3; x <= sqrtNum; x += 2)
if(num % x == 0)
a++;
pthread_mutex_lock(&lock1);
if(a == 0)
printf("%llu\n", num);
pthread_mutex_unlock(&lock);
}
return NULL;
}
int main(void)
{
pthread_t pth;
unsigned long long num, x, a, b = 0, sqrtNum;
char buff[21];
fgets(buff, 21, stdin);
sscanf(buff, "%llu", &n);
pthread_mutex_init(&lock, NULL);
pthread_mutex_init(&lock1, NULL);
pthread_create(&pth,NULL,threadFunc,"foo");
for(num = 1; num <= n; num += 4)
{
a = 0;
sqrtNum = isqrt(num);
for(x = 3; x <= sqrtNum; x += 2)
if(num % x == 0)
a++;
pthread_mutex_lock(&lock);
if(a == 0)
printf("%llu\n", num);
pthread_mutex_unlock(&lock1);
}
pthread_mutex_destroy(&lock);
pthread_mutex_destroy(&lock1);
pthread_cancel(pth);
return 0;
}
我使用互斥锁不正确吗?至于我得到它,它应该至少与一个线程一样快,但它更慢。谢谢你的帮助。
更新:我已经采用了这种方法:一个主线程计算数字的前半部分并打印出结果,另一个线程计算后半部分,并将结果存储在一个数组中。主线程完成后,它等待第二个线程完成(第二个线程计算的数字更大,需要更多时间),然后打印它的数组。不幸的是,这并不像我想的那么快,但是在非常大的数字上它可以节省很多分钟的时间。我可能稍后会尝试其他的东西。