因此,作为一项学校作业的一部分,我们被要求通过构建一个玩具程序来确定我们的个人计算机的最佳线程数。
首先,我们要创建一个运行时间为 20 到 30 秒的任务。我选择做一个抛硬币模拟,其中正面和反面的总数被累加然后显示。在我的机器上,一个线程上的 300,000,000 次抛掷以 25 秒结束。之后,我去了 2 个线程,然后是 4 个,然后是 8、16、32,为了好玩,我去了 100。 以下是结果:
* 每个线程时间抛出的线程数(秒)
* --------------------------------------
* 1 300,000,000 25
* 2 150,000,000 13
* 4 75,000,000 13
* 8 37,500,000 13
* 16 18,750,000 14
* 32 9,375,000 14
* 100 3,000,000 14
这是我使用的代码:
void toss()
{
int heads = 0, tails = 0;
default_random_engine gen;
uniform_int_distribution<int> dist(0,1);
int max =3000000; //tosses per thread
for(int x = 0; x < max; ++x){(dist(gen))?++heads:++tails;}
cout<<heads<<" "<<tails<<endl;
}
int main()
{
vector<thread>thr;
time_t st, fin;
st = time(0);
for(int i = 0;i < 100;++i){thr.push_back(thread(toss));} //thread count
for(auto& thread: thr){thread.join();}
fin = time(0);
cout<<fin-st<<" seconds\n";
return 0;
}
现在是主要问题:
超过某个点后,我预计随着更多线程的添加,计算速度会大幅下降,但结果似乎并没有表明这一点。
我的代码是否有根本性错误会产生这些类型的结果,或者这种行为是否被认为是正常的?我对多线程很陌生,所以我觉得它是前者....
谢谢!
编辑:我在配备 2.16 GHz Core 2 Duo (T7400) 处理器的 macbook 上运行此程序
最佳答案
我觉得你的结果很正常。虽然线程创建有成本,但它那么(尤其是与测试的每秒粒度相比)。我敢打赌,额外的 100 个线程创建、销毁和可能的上下文切换不会将您的时间改变超过几毫秒。
在我的 Intel i7-4790 @ 3.60 GHz 上运行我得到这些数字:
threads - seconds
-----------------
1 - 6.021
2 - 3.205
4 - 1.825
8 - 1.062
16 - 1.128
32 - 1.138
100 - 1.213
1000 - 2.312
10000 - 23.319
需要很多很多线程才能达到额外线程产生显着差异的程度。只有当我达到 1,000 个线程时,我才发现线程管理产生了显着差异,而在 10,000 个时,它使循环相形见绌(此时循环只进行了 30,000 次抛掷)。
至于您的作业,很容易看出您系统的最佳线程数应该与可同时执行的可用线程数相同。在一个线程完成或放弃之前,没有任何处理能力可以执行另一个线程,这无助于您更快地完成。而且,任何更少的线程,您都不会使用所有可用资源。我的 CPU 有 8 个线程,图表反射(reflect)了这一点。
关于c++ - 确定最佳线程数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40733112/