c++ - 带有 std::async 的函数在 Linux 上不使用多个内核
问题描述
我正在查看CppCon2019 的 Daniel Hanson的会议。它是关于在量化金融中应用现代 C++。关键思想之一是异步运行股票价格生成器,从而可以大大加快蒙特卡洛过程。
这个功能特别引起了我的注意。它在 Visual Studio 中按预期工作,但无法在我的 Linux 机器上异步运行。
void MCEuroOptPricer::computePriceAsync_() {
// a callable object that returns a `std::vector<double>` when called
EquityPriceGenerator epg(spot_, numTimeSteps_, timeToExpiry_, riskFreeRate_,
volatility_);
// fills `seeds_` (a std::vector<int>) with `std::iota`
generateSeeds_();
std::vector<std::future<std::vector<double>>> futures;
futures.reserve(numScenarios_);
for (auto &seed : seeds_) {
futures.push_back(std::async(epg, seed));
}
std::vector<double> discountedPayoffs;
discountedPayoffs.reserve(numScenarios_);
for (auto &future : futures) {
double terminalPrice = future.get().back();
double payoff = payoff_(terminalPrice);
discountedPayoffs.push_back(discFactor_ * payoff);
}
double numScens = static_cast<double>(numScenarios_);
price_ =
quantity_ * (1.0 / numScens) *
std::accumulate(discountedPayoffs.begin(), discountedPayoffs.end(), 0.0);
}
我正在使用clang++ -std=c++17 -O3
. 此并行版本的运行速度甚至比非并行版本还要慢。根据 htop,它没有使用多个内核。我试图打电话std::async
,std::launch::async
但它也没有帮助。是因为我缺少一些编译器选项还是 Visual Studio 的编译器正在应用一些我不知道的优化?如何让这个函数在 Linux 上异步运行?
不是 CS 专业的,所以我可能只是遗漏了一些明显的东西。任何帮助是极大的赞赏。
更新:事实证明,当前std::async
是在 Windows 上池化的,而不是在类 UNIX 系统上。Dmitry Danilov 的这篇文章详细解释了这一点。
我设法通过涉及boost/asio/thread_pool.hpp
.
void MCEuroOptPricer::computePriceWithPool_() {
EquityPriceGenerator epg(spot_, numTimeSteps_, timeToExpiry_, riskFreeRate_,
volatility_);
generateSeeds_();
std::vector<double> discountedPayoffs;
discountedPayoffs.reserve(numScenarios_);
std::mutex mtx; // avoid data races when writing into the vector
boost::asio::thread_pool pool(get_nprocs());
for (auto &seed : seeds_) {
boost::asio::post(pool, [&]() {
double terminalPrice = (epg(seed)).back();
double payoff = payoff_(terminalPrice);
mtx.lock();
discountedPayoffs.push_back(discFactor_ * payoff);
mtx.unlock();
});
}
pool.join();
double numScens = static_cast<double>(numScenarios_);
price_ =
quantity_ * (1.0 / numScens) *
std::accumulate(discountedPayoffs.begin(), discountedPayoffs.end(), 0.0);
}
解决方案
推荐阅读
- wso2 - WSO2 Identity Server 集群:集群中的每个节点是否需要共享一个通用的 SQL 数据库?
- html - 根据权限向用户显示/隐藏 django 应用程序中的选项
- excel - 突出显示单元格取决于其他单元格内容
- reactjs - react-beautiful-dnd:颠倒堆叠顺序?
- gnuplot - 在 gnuplot 中自动计算误差线
- asp.net - 如何将 Radiobuttonlist 放在 asp.net 上的一行下?
- r - 从事件指示器变量计算事件时间
- python - 测量两个长文本之间的相似性
- javascript - 在具有完整结构完整性的 JSON 树中搜索
- azure - Azure blob 存储,如何使用访问令牌访问所有文件内容