我正在进行一项任务,我需要计算1到1千万的素数频率。我们要通过获取变量U(1000万)并将其划分为N个部分并使多个线程计算素数的频率来实现这一点,我们必须尝试使用不同的N值并观察我们的处理器滴答和时间。计算。程序的工作方式是1000万分为N个部分,上下界被放入一个线程向量中,每个线程调用一个计算素数的函数。 现在,来自100万的素数的频率应该是664579.当进行多线程时,我的结果会略微不准确。例如,如果我运行N = 1的程序,意味着只有一个线程将解决我获得6645780的频率,其关闭1. N = 2我得到664579的正确结果,N = 3 freq = 664578,并且等等。以下是代码,非常感谢任何帮助。
#include <iostream>
#include <thread>
#include <vector>
#include<algorithm>
#define MILLION 1000000
using namespace std;
using std::for_each;
void frequencyOfPrimes(long long upper, long long lower, long long* freq)
{
long long i, j;
if (lower == 2) { *freq = upper; }
else { *freq = upper - lower; }
for (i = lower; i <= upper; ++i)
for (j = (long long)sqrt(i); j>1; --j)
if (i%j == 0) { --(*freq); break; }
return;
}
int main(int argc, char* argv[])
{
clock_t ticks = clock();
long long N = 10; //declare and initialize number of threads to calculate primes
long long U = 10*MILLION;
long long F=0; //total frequency
long long d = U / N; // the quotient of 10mil/number of threads
vector<thread> tV; //declare thread vector
vector<long long> f, u, l; //vector for freq, upper and lower bounds
f.resize(N);//initialize f
for (long long i = 0; i<N; i++) { //initialize and populate vectors for upper and lower bounds
if (i == 0) {
l.push_back(2);
u.push_back(d);
}
else {
l.push_back(u.at(i-1)+ 1);
u.push_back(u.at(i-1) + d);
}
}
u.at(N-1) = U; //make sure last thread has value of U for upper bound
for (long long i = 0; i < N; i++) { //initialize thread vectors
tV.push_back(thread(frequencyOfPrimes, u.at(i), l.at(i), &f.at(i)));
}
for_each(tV.begin(), tV.end(), mem_fn(&thread::join));
ticks = clock() - ticks;
for (long long i = 0; i < N; i++)
F = f.at(i) + F;
cout << "Frequency is " << F << endl;
cout << "It took " << ticks << " ticks (";
cout << ((float)ticks) / CLOCKS_PER_SEC << " seconds)" << endl;
this_thread::sleep_for(chrono::seconds(5));
return 0;
}
答案 0 :(得分:2)
这与多线程无关。 始终测试您的功能:
#include <iostream>
#include <cmath>
using namespace std;
// this is your function with a shorter name
void fop_strange(long long upper, long long lower, long long* freq)
{
long long i, j;
if (lower == 2) { *freq = upper; }
else { *freq = upper - lower; }
for (i = lower; i <= upper; ++i)
for (j = (long long)sqrt(i); j>1; --j)
if (i%j == 0) { --(*freq); break; }
return;
}
// attention, I switched order of upper and lower
long long fop(long long a, long long b) {
long long f = 0;
fop_strange (b, a, &f);
return f;
}
int main() {
cout << fop(2, 4) << endl;
cout << fop(10, 14) << endl;
return 0;
}
让我们先手动计算素数:
2 to 4 (inclusive) => 2 (2, 3)
10 to 14 (inclusive) => 2 (11, 13)
现在你的功能(live on ideone)
3
1
为什么呢?好吧,当你遇到非素数时,你正确地减少了计数,但你没有正确地初始化它。 2到4的范围包含3个数字,而不是4个.2到100万的范围有1 million - 2 + 1
,而不是100万个数字。 10到14的范围包括5个数字,而不仅仅是4.等等。
这解释了您获得的结果:对于从2开始的范围,您的函数返回1个数字,每隔一个范围适合1个数字。因此,当仅使用一个线程并且因此只有一个以2开头的范围时,您的结果就是一个,并且您添加的每个线程都会添加一个减少一个的范围,从而将整体结果减少一个。