【发布时间】:2015-10-05 05:02:42
【问题描述】:
我有一个 N 核处理器(在我的例子中是 4 个)。为什么 N 个线程上的 N 个完全独立的函数调用不快大约 N 倍(当然有创建线程的开销,但请进一步阅读)?
看下面的代码:
namespace ch = std::chrono;
namespace mp = boost::multiprecision;
constexpr static unsigned long long int num = 3555;
// mp_factorial uses boost/multiprecision/cpp_int, so I get legit results
ch::steady_clock::time_point s1 = ch::steady_clock::now();
auto fu1 = std::async(std::launch::async, mp_factorial, num);
auto fu2 = std::async(std::launch::async, mp_factorial, num);
auto fu3 = std::async(std::launch::async, mp_factorial, num);
auto fu4 = std::async(std::launch::async, mp_factorial, num);
fu1.get(); fu2.get(); fu3.get(); fu4.get();
ch::steady_clock::time_point e1 = ch::steady_clock::now();
ch::steady_clock::time_point s2 = ch::steady_clock::now();
mp_factorial(num);
mp_factorial(num);
mp_factorial(num);
mp_factorial(num);
ch::steady_clock::time_point e2 = ch::steady_clock::now();
auto t1 = ch::duration_cast<ch::microseconds>(e1 - s1).count();
auto t2 = ch::duration_cast<ch::microseconds>(e2 - s2).count();
cout << t1 << " " << t2 << endl;
我得到如下结果:
11756 20317
这大约快 2 倍。我也用大量的数字尝试过这个,比如num = 355555。我得到了非常相似的结果:
177462588 346575062
为什么会这样?我完全了解阿姆达尔定律,并且多核处理器并不总是快number_of_cores 倍,但是当我有独立 strong> 操作,我期待更好的结果。至少在number_of_cores 附近。
更新:
如您所见,所有线程都按预期工作,所以这不是问题:
【问题讨论】:
-
你真的有四个核心吗?还是只有两个内核和四个超线程? (例如英特尔 i3)。
-
另外:您是否检查过顺序测试中的 4 个函数调用没有内联?
-
@BaummitAugen 是的。我已经在 i7-4700MQ 上对其进行了测试。 4 个核心,8 个超线程。
-
这取决于操作系统调度程序的效率。其他程序和后台任务将被分配给内核,并从线程正在使用的一些但不是全部内核中获取量子,用户对此几乎没有控制权;很难强制操作系统将内核完全专用于程序中的线程(设置亲和性只会将线程锁定到内核,不会阻止其他进程使用它)。
-
@DanielJour 我没有。如何明确禁止内联?还没有真正考虑到这一点,这些数字很快就会变得很大,比如 5 MB-s 的内存。但是,在 DDR3 RAM 中复制 5 MB-s 并不能与 IMO 的计算相比。
标签: c++ multithreading multicore cpu-cores parallelism-amdahl