std :: async导致分段错误(或速度较慢) [英] std::async is causing segmentation fault (or slow)

查看:109
本文介绍了std :: async导致分段错误(或速度较慢)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写了简单的类来求解线性方程组,使我使用std :: async并行化矩阵行减法.在10x10矩阵大小之后,由于分段错误,程序崩溃.我的第一个实现是将 vecSub((mat [c]),(temp)); 替换为 std :: async(std :: launch :: async,vecSub,std ::ref(mat [c]),std :: ref(temp)),但随后发现,如果我们不将其分配给任何变量析构函数,则将调用.get(),并停止主线程(这是它变慢的原因),所以我将其更改为以下实现,现在出现段错误
这是单线程的:

i have written simple class to solve system of linear equations , to parallelize the matrix row subtractions i used std::async . after size of 10x10 matrix the program is crashing due to segmentation fault. my first implementation was to replace vecSub((mat[c]), (temp)); with just std::async(std::launch::async, vecSub, std::ref(mat[c]), std::ref(temp)) but then discovered that if we don't assign it to any variable destructor is called and .get() is called , and stops the main thread (which was the reason it slowed down), so i changed it to the below implementation and now i am getting seg fault
this is single threaded:

class solver
{
    Mat mat;

public:
    //give eqn in the form ax1+ax2+ax3..axN = k (coeffiants only)
    Vec solve(Mat &in)
    {

        mat = in;

        ge(mat);
        return (bs(mat));
    }
    Vec solve(Mat &&in)
    {
        mat = std::move(in);
        ge(mat);
        return (bs(mat));
    }

private:
    void ge(Mat &mat)
    {

        using li = long int;

        for (li p = 0; p < mat[0].size() - 1; p++)
        {
            for (li c = p + 1; c < mat.size(); c++)
            {
                auto x = mat[c][p] / mat[p][p];
                auto temp = mat[p];
                vecMul(x, temp);
                vecSub((mat[c]), (temp));
    
            }
        }
    }
    Vec bs(Mat &mat)
    {
        using li = long int;
        Vec x(mat.size());
        for (li i = mat.size() - 1; i >= 0; i--)
        {
            double s = 0;
            for (li j = i; j < mat[0].size() - 1; j++)
            {
                s += mat[i][j] * x[j];
                x[i] = ((mat[i][mat[0].size() - 1] - s) / (mat[i][i]));
            }
        }
        return x;
    }
    static void vecMul(double a, Vec &b)
    {
        using li = size_t;
        for (li i = 0; i < b.size(); i++)
            b[i] *= a;
    }
    //static
    static void vecAdd(Vec &a, Vec &b)
    {
        using li = size_t;
        assert(a.size() == b.size());
        for (li i = 0; i < a.size(); i++)
            a[i] = a[i] + b[i];
    }
    static void vecSub(Vec &a, Vec &b)
    {
        using li = size_t;
        assert(a.size() == b.size());
        for (li i = 0; i < a.size(); i++)
            a[i] = a[i] - b[i];
    }
};

多线程

class solver
{
    Mat mat;

public:
    //give eqn in the form ax1+ax2+ax3..axN = k (coeffiants only)
    Vec solve(Mat &in)
    {

        mat = in;

        ge(mat);
        return (bs(mat));
    }
    Vec solve(Mat &&in)
    {
        mat = std::move(in);
        ge(mat);
        return (bs(mat));
    }

private:
    void ge(Mat &mat)
    {

        using li = long int;

        for (li p = 0; p < mat[0].size() - 1; p++)
        {
            std::vector<std::future<void>> ts;

            for (li c = p + 1; c < mat.size(); c++)
            {
                auto x = mat[c][p] / mat[p][p];
                auto temp = mat[p];
                vecMul(x, temp);
                ts.push_back(std::async(std::launch::async, vecSub, std::ref(mat[c]), std::ref(temp)));
            }
            for (auto &t : ts)
            {

                t.get();
            }
        }
    }
    Vec bs(Mat &mat)
    {
        using li = long int;
        Vec x(mat.size());
        for (li i = mat.size() - 1; i >= 0; i--)
        {
            double s = 0;
            for (li j = i; j < mat[0].size() - 1; j++)
            {
                s += mat[i][j] * x[j];
                x[i] = ((mat[i][mat[0].size() - 1] - s) / (mat[i][i]));
            }
        }
        return x;
    }
    static void vecMul(double a, Vec &b)
    {
        using li = size_t;
        for (li i = 0; i < b.size(); i++)
            b[i] *= a;
    }
    //static
    static void vecAdd(Vec &a, Vec &b)
    {
        using li = size_t;
        assert(a.size() == b.size());
        for (li i = 0; i < a.size(); i++)
            a[i] = a[i] + b[i];
    }
    static void vecSub(Vec &a, Vec &b)
    {
        using li = size_t;
        // assert(a.size() == b.size());
        for (li i = 0; i < a.size(); i++)
            a[i] = a[i] - b[i];
    }
};

细分发生在

static void vecSub(Vec &a, Vec &b)
    {
        using li = size_t;
        assert(a.size() == b.size());
        for (li i = 0; i < a.size(); i++)
            a[i] = a[i] - b[i];
    }

推荐答案

无论 Mat 类型是什么,我都很确定:

Whatever the Mat type is, I'm pretty sure this:

auto temp = mat[p];

不会创建参考,而是创建副本.就是这个

does not create a reference but a copy. It means this

ts.push_back(std::async(std::launch::async, vecSub, std::ref(mat[c]), std::ref(temp)));`

实际上引用了一个临时值 temp ,该临时值将在此循环结束时销毁.这是未定义的行为.
这可能可以解决问题:

actually makes a reference to a temporary value temp which is about to be destroyed at the end of this loop. That's undefined behavior.
This could possibly fix the issue:

auto& temp = mat[p];

这篇关于std :: async导致分段错误(或速度较慢)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆