C++ 计算由多个线程同时调用的方法中任务的持续时间

C++ 计算由多个线程同时调用的方法中任务的持续时间,c++,c++11,C++,C++11,我创建了一个成员函数,它同时被多个线程调用。在这个函数中,我想计算函数执行的总持续时间。问题是,例如,如果我创建4个线程,返回的时间是实际时间的4倍!我怎样才能知道实际时间?我的方法如下所示: void Class1::myTask() { //...code chrono::steady_clock::time_point start = chrono::steady_clock::now(); theFunction(); chrono::steady_clock::time_poi

我创建了一个成员函数,它同时被多个线程调用。在这个函数中,我想计算函数执行的总持续时间。问题是,例如,如果我创建4个线程,返回的时间是实际时间的4倍!我怎样才能知道实际时间?我的方法如下所示:

void Class1::myTask() {

//...code

chrono::steady_clock::time_point start = chrono::steady_clock::now();

theFunction();

chrono::steady_clock::time_point end = chrono::steady_clock::now();
chrono::duration<double> time_span = chrono::duration_cast<chrono::duration<double>>(end - start);
mytime = time_span.count();  // mytime is of atomic type

setTheTime(mytime); 

//...more code
} 

// The method to set the Total Time
void Class1::setTheTime(double mTime){
  time = time + mTime; // time is of atomic type
}

假设有N个线程,它们在X秒自然时间内并行运行

因此,随着时间的推移,它们不断积累 S=N*X

大致上成立

44秒实际上等于4*11秒


那么问题出在哪里呢

我不认为时间=时间+时间;是有效的,即使是原子类型,但我不确定time+=mTime是否更好。Elevent,我发现带前导m前缀的参数令人困惑,并希望它们是成员。前缀很抱歉。time和mytime是双重类型。为什么这会成为一个问题?如果我把数字加起来,我的意思是:@MooingDuck是正确的,time=time+mTime;不是原子读修改写操作。时间+=mTime;是一个原子读修改写操作。不幸的是,运算符+=没有为通用std::atomic模板定义-仅为其整数专门化定义。有关详细信息,请参阅。通过使用时间的整数类型,可以完全避免原子问题:std::atomic可能是理想的。实际总时间为11秒4*2,75,而不是44。您所指的总时间就像从手表上取下的时间。这种手表是单线程的。实际并行执行中的4个线程。就像在多个核上一样,它们的累计寿命是同期的4倍。这就是真正的多线程。所以我想我想要实现的事情是做不到的。。真遗憾。我发现的最后一件事可以在这里看到。我运行了它,但是类似的事情发生了,尽管它说它是多线程安全的,但我并不是说你不能达到你想要的。我只是想证明问题其实没有。当然,您可以在每个线程的基础上进行配置-只需在每个线程中使用一次累加器。例如,array或std::valarrayN,如果需要动态线程,则使用后者。
#include <iostream>
#include <cstdlib>
#include <string>
#include <vector>
#include <thread>
#include <chrono>
#include <atomic>
using namespace std;

atomic<double> time1;
atomic<double> mytime;

void theFunction() {
    int x = 0;
    for (int i = 0; i < 10000000; ++i) {
        x++;
    }
}

double setTheTime(double mTime1) {
    time1 = time1 + mTime1;
}

void countTime() {

    chrono::steady_clock::time_point start = chrono::steady_clock::now();

    theFunction();

    chrono::steady_clock::time_point end = chrono::steady_clock::now();
    chrono::duration<double> time_span = chrono::duration_cast<chrono::duration<double>>(end - start);
    mytime = time_span.count();

    setTheTime(mytime);
}

int main(int argc, char** argv) {

    vector<thread> threads;
    long double mt;

    chrono::steady_clock::time_point start = chrono::steady_clock::now();

    for (int i = 0; i < 4; i++)
        threads.push_back(thread(countTime));

    for (auto& thread : threads)
        thread.join();

    chrono::steady_clock::time_point end = chrono::steady_clock::now();
    chrono::duration<double> time_span = chrono::duration_cast<chrono::duration<double>>(end - start);
    mt = time_span.count(); // mytime is of atomic type
    cout << "Time out of the function: " << mt * 1000 << endl;
    cout << "Time inside the function: " << time1 * 1000 << endl;
    return 0;
}