为什么for循环中的异步不能提高执行时间
Why does async in a for loop not improve execution time?
我正在努力了解并发性,所以我试图从《C++教程》(第二版(15.7.3第205页中编写一个更灵活的版本(my_comp(((的Stroustrup示例代码(comp4(((。它给出了正确的答案,但没有使用并发来提高执行时间。我的问题是:为什么My_comp((没有按预期运行,我该如何修复它?
#include <iostream>
#include <chrono>
#include <cmath>
#include <vector>
#include <numeric>
#include <future>
#include <fstream>
using namespace std;
using namespace std::chrono;
constexpr auto sz = 500'000'000;
constexpr int conc_num{ 4 };
double accum(double* beg, double* end, double init)
{
return accumulate(beg, end, init);
}
double comp4(vector<double>& v)
//From Stroustrup, A Tour of C++ (Second edition)
//15.7.3 page 205
{
auto v0 = &v[0];
auto sz = v.size();
auto f0 = async(accum, v0, v0 + sz / 4, 0.0);
auto f1 = async(accum, v0 + sz / 4, v0 + sz / 2, 0.0);
auto f2 = async(accum, v0 + sz / 2, v0 + sz * 3 / 4, 0.0);
auto f3 = async(accum, v0 + sz * 3 / 4, v0 + sz, 0.0);
return f0.get() + f1.get() + f2.get() + f3.get();
}
double my_comp(vector<double>& v, int conc = 1)
//My idea of a more flexible version of comp4
{
if (conc < 1)
conc = 1;
auto v0 = &v[0];
auto sz = v.size();
vector<future<double>> fv(conc);
for (int i = 0; i != conc; ++i) {
auto f = async(accum, v0 + sz * (i / conc), v0 + sz * ((i + 1) / (conc)), 0.0);
fv[i] = move(f);
}
double ret{ 0.0 };
for (int i = 0; i != fv.size(); ++i) {
ret += fv[i].get();
}
return ret;
}
int main()
{
cout << "Calculating ..." << "nn";
auto tv0 = high_resolution_clock::now();
vector<double> vc;
vc.reserve(sz);
for (int i = 0; i != sz; ++i) {
vc.push_back(sin(i)); //Arbitrary test function
}
auto tv1 = high_resolution_clock::now();
auto durtv = duration_cast<milliseconds>(tv1 - tv0).count();
cout << "vector of size " << vc.size() << ": " << durtv << " msecnn";
////////////////////////////////////////////
auto vc_test = vc;
auto t0 = high_resolution_clock::now();
auto s1 = accumulate(vc_test.begin(), vc_test.end(), 0.0);
auto t1 = high_resolution_clock::now();
auto dur1 = duration_cast<milliseconds>(t1 - t0).count();
///////////////////////////////////////////
vc_test = vc;
auto tt0 = high_resolution_clock::now();
auto s2 = my_comp(vc_test, conc_num); //Should be faster
auto tt1 = high_resolution_clock::now();
auto dur2 = duration_cast<milliseconds>(tt1 - tt0).count();
////////////////////////////////////////////
vc_test = vc;
auto ttt0 = high_resolution_clock::now();
auto s3 = comp4(vc_test); //Really is faster
auto ttt1 = high_resolution_clock::now();
auto dur3 = duration_cast<milliseconds>(ttt1 - ttt0).count();
///////////////////////////////////////////
cout << dur1 << " msecn";
cout << "Output = " << s1 << " (accumulate)" << "nn";
cout << dur2 << " msec" << " Ratio: " << double(dur2) / double(dur1) << "n";
cout << "Output = " << s2 << " (my_comp)" << "nn";
cout << dur3 << " msec" << " Ratio: " << double(dur3) / double(dur1) << "n";
cout << "Output = " << s3 << " (comp4)" << "nn";
}
使用Visual C++2019(ISO C++17 Standard(/std:C++17((X64版本编译。典型的输出是:
424毫秒输出=1.93496(累加(
431毫秒比率:1.01651输出=1.93496(my_comp(
117毫秒比率:0.275943输出=1.93496(comp4(
我知道并行算法和std::reduce。我的问题不是如何优化这个特定的计算,而是学习如何编写符合预期的并发代码。
您的问题在这里:(i / conc)
。一旦0 <= i < conc
、i
和conc
是整数,这意味着该计算总是零。
要解决您的问题,请删除括号:
auto f = async(accum, v0 + sz * i / conc, v0 + sz * (i + 1) / conc, 0.0);
相关文章:
- C++从其他 constexpr 创建 lambda 不能按顺序执行 Constexpr
- 为什么 std::chrono 在测量循环和编译器优化的并行 OpenMP 的执行时间时不起作用?
- 如果普通默认构造函数不执行任何操作,为什么我们不能使用 malloc 创建平凡可构造的对象?
- 为什么for循环中的异步不能提高执行时间
- Qt不能多次执行线程
- 在我的测试程序中,为什么 cv::resize 不能执行,而 cvtColor 可以?
- clEnqueueWriteImage 在执行时间上不稳定
- 我可以固定C 可执行文件,但不能共享库
- 为什么将可执行文件重命名为临时文件的此代码段不能按预期工作?
- CUDA 程序不测量执行时间:cuda事件记录
- 为什么我的执行时间不会写入文件?
- GPROF分析工具是不准确的执行时间
- 在我的CUDA运行时间计划中,CPU和GPU可以异步计算,但不能合作地计算
- 为什么函数 sleep() 在 klee 执行 Objectfile 时不能工作?
- 为什么我不能通过执行 "myVector[i].data()" 来实例化一个类,其中 myVector[i].data() 是一个字符串?
- 在一个简单的高峰时间求解器中使用BFS——为什么我的代码不能求解棋盘
- QT删除可与Valgrind一起使用,但不能正常执行
- 函数不能嵌套,那么如何在C++中执行此操作
- 为什么我不能复制这样的可执行文件?
- 如果可执行文件在两个或多个节点上运行,为什么它不能看到环境变量?