C++ 没有加速?

C++ 没有加速?,c++,boost-thread,C++,Boost Thread,我有一个小程序,使用各种卡片计数策略来实现21点的蒙特卡罗模拟。我的主要功能是: int bankroll = 50000; int hands = 100; int tests = 10000; Simulation::strategy = hi_lo; for(int i = 0; i < simulations; ++i) runSimulation(bankroll, hands, tests, strategy); int-bankroll=50000; int han

我有一个小程序,使用各种卡片计数策略来实现21点的蒙特卡罗模拟。我的主要功能是:

int bankroll = 50000;
int hands = 100;
int tests = 10000;
Simulation::strategy = hi_lo;

for(int i = 0; i < simulations; ++i)
   runSimulation(bankroll, hands, tests, strategy);
int-bankroll=50000;
int hands=100;
int测试=10000;
模拟::策略=高低;
对于(int i=0;i
在我的机器上,整个程序在一个线程中运行大约需要10秒

我想利用我的处理器拥有的3个内核,因此我决定重写程序,以便在单独的线程中简单地执行各种策略,如下所示:

int bankroll = 50000;
int hands = 100;
int tests = 10000;
Simulation::strategy = hi_lo;
boost::thread threads[simulations];

for(int i = 0; i < simulations; ++i)
   threads[i] = boost::thread(boost::bind(runSimulation, bankroll, hands, tests, strategy));

for(int i = 0; i < simulations; ++i)
   threads[i].join();
int-bankroll=50000;
int hands=100;
int测试=10000;
模拟::策略=高低;
boost::线程[模拟];
对于(int i=0;i

然而,当我运行这个程序时,尽管我得到了相同的结果,但它大约需要24秒才能完成。我错过了什么吗?

如果
模拟的值很高,那么最终会创建很多线程,这样做的开销可能会破坏任何可能的性能提升


编辑:一种方法可能是只启动三个线程,让它们各自运行所需模拟的1/3。或者,使用某种类型的线程池也会有所帮助。

这是使用线程池的工作队列的一个很好的候选者。我使用英特尔线程块(TBB)来满足这些要求。也可以使用手工制作的线程池进行快速破解。在Windows上,操作系统为您提供了一个很好的线程池备份工作队列
我同意德列夫的观点。如果函数runSimulation没有更改下一次调用“runSimulation”正常工作所需的任何内容,则可以执行以下操作:

. 将“模拟”除以3。

. 现在将有3个计数器“0到模拟/3”“(模拟/3+1)到2模拟/3”和“2*模拟)/3+1到模拟”。 所有这3个计数器可以同时在三个不同的线程中使用。

**注意::**您的要求可能根本不适用于这种类型的检查,以防您必须执行共享数据锁定和所有操作

阅读Herb Sutter的这些文章。你可能是“虚假分享”的受害者


我参加这个聚会迟到了,但我想为看到这篇文章的其他人指出两件事:

1) 当然可以看到David指出的第二个Herb Sutter链接(http://www.drdobbs.com/parallel/eliminate-false-sharing/217500206). 它解决了将我带到这个问题的问题,概述了一个struct数据对象包装器,确保不同的并行线程不会争夺总部位于同一内存缓存线上的资源(硬件控制将防止多个线程同时访问同一内存缓存线)

2) 关于最初的问题,德列夫指出了问题的很大一部分,但由于这是一个模拟,我打赌有一个更深层次的问题使事情变得缓慢。虽然没有共享程序的高级变量,但您可能有一个共享的关键系统变量:存储在引擎盖下并用于创建下一个随机数的系统级“last random number”。您甚至可能会为每次模拟初始化专用生成器对象,但如果它们正在调用诸如rand()之类的函数,那么它们以及它们的线程将重复调用同一共享系统资源,并随后相互阻塞


问题2的解决方案取决于模拟程序本身的结构。例如,如果对随机生成器的调用是分段的,那么我可能会将其批处理为一个预先调用,该调用检索并存储模拟所需的内容。这让我现在想知道更复杂的方法,可以处理潜在的随机生成共享资源问题

你检查过这个程序是否使用了所有的内核吗?我也这么想。事实上,我的处理器正好有3个内核,所以我尝试使用一个每次运行3个线程的循环运行,并在循环之前对所有3个线程进行连接,但没有看到明显的改进。我观察了在我的系统上运行的进程,发现在单线程系统中只有1个内核被使用,而在所有其他版本中,所有3个内核都被使用,但仍然没有加速。没有一个变量是共享的,因为它们都是单独的模拟,并且彼此独立。