尝试创建一个多线程程序来查找 0-100000000 之间的总素数
Trying to create a multithreaded program to find the total primes from 0-100000000
你好我正在尝试使用 POSIX 线程库编写一个 C++ 多线程程序来查找 1 到 10,000,000(一千万)之间的质数个数,并找出它需要多少微秒...
创建我的线程并且 运行 它们工作得很好,但是我觉得在确定一个数字是否为质数时好像在我的 Prime 函数中发现了一个错误...
我一直收到 78496 作为我的输出,但我想要 664579。下面是我的代码。任何提示或指示将不胜感激。
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <unistd.h>
#include <iostream>
#include <sys/time.h> //measure the execution time of the computations
using namespace std;
//The number of thread to be generated
#define NUMBER_OF_THREADS 4
void * Prime(void* index);
long numbers[4] = {250000, 500000, 750000, 1000000};
long start_numbers[4] = {1, 250001, 500001, 750001};
int thread_numbers[4] = {0, 1, 2, 3};
int main(){
pthread_t tid[NUMBER_OF_THREADS];
int tn;
long sum = 0;
timeval start_time, end_time;
double start_time_microseconds, end_time_microseconds;
gettimeofday(&start_time, NULL);
start_time_microseconds = start_time.tv_sec * 1000000 + start_time.tv_usec;
for(tn = 0; tn < NUMBER_OF_THREADS; tn++){
if (pthread_create(&tid[tn], NULL, Prime, (void *) &thread_numbers[tn]) == -1 ) {
perror("thread fail");
exit(-1);
}
}
long value[4];
for(int i = 0; i < NUMBER_OF_THREADS; i++){
if(pthread_join(tid[i],(void **) &value[i]) == 0){
sum = sum + value[i]; //add four sums together
}else{
perror("Thread join failed");
exit(-1);
}
}
//get the end time in microseconds
gettimeofday(&end_time, NULL);
end_time_microseconds = end_time.tv_sec * 1000000 + end_time.tv_usec;
//calculate the time passed
double time_passed = end_time_microseconds - start_time_microseconds;
cout << "Sum is: " << sum << endl;
cout << "Running time is: " << time_passed << " microseconds" << endl;
exit(0);
}
//Prime function
void* Prime(void* index){
int temp_index;
temp_index = *((int*)index);
long sum_t = 0;
for(long i = start_numbers[temp_index]; i <= numbers[temp_index]; i++){
for (int j=2; j*j <= i; j++)
{
if (i % j == 0)
{
break;
}
else if (j+1 > sqrt(i)) {
sum_t++;
}
}
}
cout << "Thread " << temp_index << " terminates" << endl;
pthread_exit( (void*) sum_t);
}```
这是因为,您使用的是 10^6 而不是 10^7。
此外,为数字 1、2 和 3 添加了一些极端情况:
//Prime function
void* Prime(void* index){
int temp_index;
temp_index = *((int*)index);
long sum_t = 0;
for(long i = start_numbers[temp_index]; i <= numbers[temp_index]; i++){
// Corner cases
if(i<=1)continue;
if (i <= 3){
sum_t++;
continue;
}
for (int j=2; j*j <= i; j++)
{
if ((i % j == 0) || (i %( j+2))==0 )
{
break;
}
else if (j+1 > sqrt(i)) {
sum_t++;
}
}
}
cout << "Thread " << temp_index << " terminates" << endl;
pthread_exit( (void*) sum_t);
}
我用正确的数字测试了你的代码,得到了正确的素数作为输出:
Thread 0 terminates
Thread 1 terminates
Thread 2 terminates
Thread 3 terminates
Sum is: 664579
Running time is: 4.69242e+07 microseconds
感谢@chux - Reinstate Monica 指出了这一点
除了将 10^7 作为线程划分的数字而不是将限制设置为 10^6 之外,还有许多其他小规模错误,并且可以进行一些优化 -
首先起始号码可以是2本身
long start_numbers[4] = {2, 2500001, 5000001, 7500001};
sum_t++ 在您的代码中可能不适用于边缘情况。最好按照下面的算法计算Prime函数
bool flag = false;
for(long i = start_numbers[temp_index]; i <= numbers[temp_index]; i++){
flag = false;
for (long j=2; j*j <= i; j++){
if (i % j == 0 )
{
flag = true;
break;
}
}
if(!flag)
sum_t++;
}
在这 2 个操作之后,我得到的结果是
Thread 0 terminates
Thread 1 terminates
Thread 2 terminates
Thread 3 terminates
Sum is: 664579
Running time is: 6.62618e+06 microseconds
编辑:
(注意:在这种情况下,j
被视为 long
数据类型,但在 'example' 中它也可以与 int
一起工作,因为经过测试的编译器将 int
作为32 位长)
你好我正在尝试使用 POSIX 线程库编写一个 C++ 多线程程序来查找 1 到 10,000,000(一千万)之间的质数个数,并找出它需要多少微秒...
创建我的线程并且 运行 它们工作得很好,但是我觉得在确定一个数字是否为质数时好像在我的 Prime 函数中发现了一个错误...
我一直收到 78496 作为我的输出,但我想要 664579。下面是我的代码。任何提示或指示将不胜感激。
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <unistd.h>
#include <iostream>
#include <sys/time.h> //measure the execution time of the computations
using namespace std;
//The number of thread to be generated
#define NUMBER_OF_THREADS 4
void * Prime(void* index);
long numbers[4] = {250000, 500000, 750000, 1000000};
long start_numbers[4] = {1, 250001, 500001, 750001};
int thread_numbers[4] = {0, 1, 2, 3};
int main(){
pthread_t tid[NUMBER_OF_THREADS];
int tn;
long sum = 0;
timeval start_time, end_time;
double start_time_microseconds, end_time_microseconds;
gettimeofday(&start_time, NULL);
start_time_microseconds = start_time.tv_sec * 1000000 + start_time.tv_usec;
for(tn = 0; tn < NUMBER_OF_THREADS; tn++){
if (pthread_create(&tid[tn], NULL, Prime, (void *) &thread_numbers[tn]) == -1 ) {
perror("thread fail");
exit(-1);
}
}
long value[4];
for(int i = 0; i < NUMBER_OF_THREADS; i++){
if(pthread_join(tid[i],(void **) &value[i]) == 0){
sum = sum + value[i]; //add four sums together
}else{
perror("Thread join failed");
exit(-1);
}
}
//get the end time in microseconds
gettimeofday(&end_time, NULL);
end_time_microseconds = end_time.tv_sec * 1000000 + end_time.tv_usec;
//calculate the time passed
double time_passed = end_time_microseconds - start_time_microseconds;
cout << "Sum is: " << sum << endl;
cout << "Running time is: " << time_passed << " microseconds" << endl;
exit(0);
}
//Prime function
void* Prime(void* index){
int temp_index;
temp_index = *((int*)index);
long sum_t = 0;
for(long i = start_numbers[temp_index]; i <= numbers[temp_index]; i++){
for (int j=2; j*j <= i; j++)
{
if (i % j == 0)
{
break;
}
else if (j+1 > sqrt(i)) {
sum_t++;
}
}
}
cout << "Thread " << temp_index << " terminates" << endl;
pthread_exit( (void*) sum_t);
}```
这是因为,您使用的是 10^6 而不是 10^7。
此外,为数字 1、2 和 3 添加了一些极端情况:
//Prime function
void* Prime(void* index){
int temp_index;
temp_index = *((int*)index);
long sum_t = 0;
for(long i = start_numbers[temp_index]; i <= numbers[temp_index]; i++){
// Corner cases
if(i<=1)continue;
if (i <= 3){
sum_t++;
continue;
}
for (int j=2; j*j <= i; j++)
{
if ((i % j == 0) || (i %( j+2))==0 )
{
break;
}
else if (j+1 > sqrt(i)) {
sum_t++;
}
}
}
cout << "Thread " << temp_index << " terminates" << endl;
pthread_exit( (void*) sum_t);
}
我用正确的数字测试了你的代码,得到了正确的素数作为输出:
Thread 0 terminates
Thread 1 terminates
Thread 2 terminates
Thread 3 terminates
Sum is: 664579
Running time is: 4.69242e+07 microseconds
感谢@chux - Reinstate Monica 指出了这一点
除了将 10^7 作为线程划分的数字而不是将限制设置为 10^6 之外,还有许多其他小规模错误,并且可以进行一些优化 -
首先起始号码可以是2本身
long start_numbers[4] = {2, 2500001, 5000001, 7500001};
sum_t++ 在您的代码中可能不适用于边缘情况。最好按照下面的算法计算Prime函数
bool flag = false; for(long i = start_numbers[temp_index]; i <= numbers[temp_index]; i++){ flag = false; for (long j=2; j*j <= i; j++){ if (i % j == 0 ) { flag = true; break; } } if(!flag) sum_t++; }
在这 2 个操作之后,我得到的结果是
Thread 0 terminates
Thread 1 terminates
Thread 2 terminates
Thread 3 terminates
Sum is: 664579
Running time is: 6.62618e+06 microseconds
编辑:
(注意:在这种情况下,j
被视为 long
数据类型,但在 'example' 中它也可以与 int
一起工作,因为经过测试的编译器将 int
作为32 位长)