加速提升中的多线程

时间:2017-05-02 15:17:19

标签: multithreading

我写了一个程序来计算2乘2随机矩阵的特征值。我生成了50,000个2x2随机矩阵并计算了它们的特征值。

使用boost,我在getEigVal()的成员函数myClass中使用了多线程,但我发现CPU利用率只有35%。

如何通过多线程加快getEigVal()的过程?

#define _USE_MATH_DEFINES 
#define _USE_MATH_DEFINES
#define BOOST_THREAD_PROVIDES_FUTURE
#include <boost/thread.hpp>
#include <boost/thread/future.hpp>
#include <vector>
#include <cmath>
#include <random>
#include <complex>
#include <chrono>

using namespace std;
using namespace std::chrono;

class myClass {

private:

int numOfRun;
double var;
vector <vector<complex<double>>> eigVal;

vector<complex<double>> quad_root(double a, double b, double c) {//quadratic formula

    vector<complex<double>> root(2, complex<double>(0, 0));
    complex<double> delta = sqrt(complex<double>(pow(b, 2) - 4 * a*c, 0));

    root[0] = (-b + delta) / 2.0 / a;
    root[1] = (-b - delta) / 2.0 / a;

    return root;
}

vector<complex<double>> eig(vector<vector<double>> A) {//compute eigenvalues

    double a = 1.0;
    double b = -A[0][0] - A[1][1];
    double c = A[0][0] * A[1][1] - A[0][1] * A[1][0];
    vector<complex<double>> r = quad_root(a, b, c);

    return r;
}


public:
myClass(int run = 5e4, double v = 1) :
    numOfRun(run), var(v), eigVal(numOfRun, vector<complex<double>>(2)){
}


vector <vector<complex<double>>> getEigVal() {

    random_device rd;
    mt19937 e2(rd());
    normal_distribution<> a(0.0, var);
    vector <vector<double>> A(2, vector<double>(2));

    for (int i = 0; i < numOfRun; i++) {

        A = { { a(e2), a(e2) }, { a(e2), a(e2) } };//generate a 2x2 random matrix

        boost::packaged_task<vector<complex<double>>> task{ bind(&myClass::eig, this, A) };
        boost::future<vector<complex<double>>> f = task.get_future();
        boost::thread t{ std::move(task) };
        eigVal[i] = f.get();
    }

    return eigVal;
}
};

int main() {

myClass Test;

auto start = steady_clock::now();
vector <vector<complex<double>>> result = Test.getEigVal();
auto end = steady_clock::now();

cout << "Time elapsed: " << (duration_cast<milliseconds>(end - start).count())/1e3 << " seconds\n";//13.826 s

return 0;

}

0 个答案:

没有答案