c++ 为什么 std::async 比顺序执行慢

标签 c++ multithreading c++11 asynchronous

#include <future>
#include <iostream>
#include <vector>
#include <cstdint>
#include <algorithm>
#include <random>
#include <chrono>
#include <utility>
#include <type_traits>

template <class Clock = std::chrono::high_resolution_clock, class Task>
double timing(Task&& t, typename std::result_of<Task()>::type* r = nullptr)
{
  using namespace std::chrono;
  auto begin = Clock::now();
  if (r != nullptr) *r = std::forward<Task>(t)();
  auto end = Clock::now();
  return duration_cast<duration<double>>(end - begin).count();
}

template <typename Num>
double sum(const std::vector<Num>& v, const std::size_t l, const std::size_t h)
{
  double s;
  for (auto i = l; i <= h; i++) s += v[i];
  return s;
}

template <typename Num>
double asum(const std::vector<Num>& v, const std::size_t l, const std::size_t h)
{
  auto m = (l + h) / 2;
  auto s1 = std::async(std::launch::async, sum<Num>, v, l, m);
  auto s2 = std::async(std::launch::async, sum<Num>, v, m+1, h);
  return s1.get() + s2.get();
}

int main()
{
  std::vector<uint> v(1000);
  auto s = std::chrono::system_clock::now().time_since_epoch().count();
  std::generate(v.begin(), v.end(), std::minstd_rand0(s));

  double r;
  std::cout << 1000 * timing([&]() -> double { return asum(v, 0, v.size() - 1); }, &r) << " msec | rst " << r << std::endl;
  std::cout << 1000 * timing([&]() -> double { return sum(v, 0, v.size() - 1); }, &r) << " msec | rst " << r << std::endl;
}

你好,

以上是对随机数 vector 求和的两个函数。

我运行了几次,但似乎我没有从 std::async 中获益。以下是我得到的一些结果。

0.130582 msec | rst 1.09015e+12
0.001402 msec | rst 1.09015e+12

0.23185 msec | rst 1.07046e+12
0.002308 msec | rst 1.07046e+12

0.18052 msec | rst 1.07449e+12
0.00244 msec | rst 1.07449e+12

0.190455 msec | rst 1.08319e+12
0.002315 msec | rst 1.08319e+12

在所有四种情况下,异步版本都花费了更多时间。但理想情况下,我应该快两倍,对吧?

我的代码中是否遗漏了任何内容?

顺便说一下,我在 OS X 10.10.4 Macbook Air 上运行 1.4 GHz Intel Core i5

谢谢,

编辑:

  1. 编译器标志:g++ -o asum asum.cpp -std=c++11
  2. 我将标志更改为包括 -O3 并将 vector 大小更改为 10000000,但结果仍然很奇怪。

72.1743 msec | rst 1.07349e+16
14.3739 msec | rst 1.07349e+16

58.3542 msec | rst 1.07372e+16
12.1143 msec | rst 1.07372e+16

57.1576 msec | rst 1.07371e+16
11.9332 msec | rst 1.07371e+16

59.9104 msec | rst 1.07395e+16
11.9923 msec | rst 1.07395e+16

64.032 msec | rst 1.07371e+16
12.0929 msec | rst 1.07371e+16

最佳答案

这里

auto s1 = std::async(std::launch::async, sum<Num>, v, l, m);
auto s2 = std::async(std::launch::async, sum<Num>, v, m+1, h);

async 将存储自己的 vector 拷贝,两次。您应该使用 std::cref 并确保在 vector 终止之前检索到 futures(因为它在您当前的代码中)并且访问得到正确同步(因为它在您当前的代码中)。

如评论中所述,线程创建开销可能会进一步降低代码速度。

关于c++ 为什么 std::async 比顺序执行慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47183731/

相关文章:

java - 为什么 Future isDone() 会像 Future get() 一样阻塞程序?

java - 如果操作系统挂起,正在 sleep 的线程会发生什么?

c++ - 移动 basic_iostream 时 basic_ostream 基会发生什么变化?

c++ - 使用 Spirit x3,如何控制在每个不同的输入上调用哪个解析器?

java - 在内部类运行中使用变量

c++ - 对c++ vector 的交集

c++ - 有没有一种方法可以机械地识别哪些操作对移出的对象是安全的?

c++ - 如何在 block 复制期间向量化范围检查?

c++ - OpenCV C++ 视频捕获似乎不起作用

c++ - 在 C++ 中多线程模拟