【发布时间】:2021-05-11 10:32:39
【问题描述】:
我应该使用多线程来改进此代码,以便在不到 6 秒的时间内对一百万个随机生成的整数的所有素数进行求和和计数。我的教授不到一秒钟就完成了我该怎么做,所以我被卡住了。
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <math.h>
int isPrime(int num) {
int i;
for (i = 2; i < num; i++) {
if (num % i == 0) {
return 0;
}
}
return 1;
}
int main(int argc, char *argv[]) {
if (argc != 3) {
printf("Too few arguments ");
printf("USAGE: ./primeCalc <prime pivot> <num of random numbers>");
exit(0);
}
int randomPivot = atoi(argv[1]);
int numOfRandomNumbers = atoi(argv[2]);
long sum = 0;
long primeCounter = 0;
//init rundom generator
int random = rand();
srand(randomPivot);
//generate random numbers
for (int i = 0; i < numOfRandomNumbers; i++) {
random = rand();
//check if the number is prime
if (isPrime(random)) {
//if do, add up it's sum, and increment counter
sum = sum + random;
primeCounter++;
}
}
//keep the out format as this!!
printf("%ld,%ld\n", sum, primeCounter);
exit(0);
}
我尝试使用此代码,但由于某种原因,输出错误,即使我使用了 3 个线程,它也只使用了 1 个内核。
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <math.h>
pthread_mutex_t lock;
long count1 = 0, count2 = 0, count3 = 0;
long sum1 = 0, sum2 = 0, sum3 = 0;
void *isPrime1(void *x) {
int i; int num = *(int*)x;
if (num < 2)
return NULL;
if (num == 2)
return NULL;
{
sum1 += num;
count1 += 1;
}
if (num % 2 == 0)
return NULL;
for (i = 3; i * i < num; i = i + 2) {
if (num % i == 0) {
return NULL;
}
}
sum1 += num;
count1 += 1;
return NULL;
}
void *isPrime2(void *x) {
int i;
int num = *(int*)x;
if (num < 2)
return NULL;
if (num == 2)
return NULL;
{
sum2 += num;
count2 += 1;
}
if (num % 2 == 0)
return NULL;
for (i = 3; i * i < num; i = i + 2) {
if (num % i == 0) {
return NULL;
}
}
sum2 += num;
count2 += 1;
return NULL;
}
void *isPrime3(void *x) {
int i;
int num = *(int*)x;
if (num < 2)
return NULL;
if (num == 2)
return NULL;
{
sum3 += num;
count3 += 1;
}
if (num % 2 == 0)
return NULL;
for (i = 3; i * i < num; i = i + 2) {
if (num % i == 0) {
return NULL;
}
}
sum3 += num;
count3 += 1;
return NULL;
}
int main(int argc, char *argv[]) {
if (pthread_mutex_init(&lock, NULL) != 0) {
printf("mutix init failed\n");
return 0;
}
pthread_t tids[3];
if (argc != 3) {
printf("Too few arguments ");
printf("USAGE: ./primeCalc <prime pivot> <num of random numbers>");
exit(0);
}
int randomPivot = atoi(argv[1]);
int numOfRandomNumbers = atoi(argv[2]);
//init rundom generator
int random = rand();
srand(randomPivot);
//generate random numbers
for (int i = 0; i < numOfRandomNumbers; i += 3) {
random = rand();
pthread_create((&tids[0]), NULL, isPrime1, &random);
random = rand();
pthread_create((&tids[1]), NULL, isPrime2, &random);
random = rand();
pthread_create((&tids[2]), NULL, isPrime3, &random);
}
for (int j = 0; j < 3; j++)
pthread_join(tids[j], NULL);
long sum = sum1 + sum2 + sum3;
long count = count1 + count2 + count3;
//keep the out format as this!!
printf("%ld,%ld\n", sum, count);
exit(0);
}
【问题讨论】:
-
第二件事要尝试:检查一次奇数/偶数...然后只检查奇数:
for (i = 3; i < num; i += 2) { ... }。首先,请参阅@qrdl 的评论 :-) -
你做了什么来试图摆脱“卡住”?
-
for (i = 2;i<num;i++)- 你需要迭代到num吗? -
您的代码现在不使用任何线程。它应该。
-
假设所有输入值都适合
int,首先找到直到INT_MAX平方根的所有素数并将它们存储在一个表(数组)中。然后,对于每个候选数,测试它是否可以被每个存储的素数整除(但不等于存储的数字)。如果是,则不是素数。否则,它是素数。 (例外:如果候选项小于 2,则它既不是质数也不是合数。)
标签: c