Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/163.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ std::async导致分段错误(或速度慢)_C++_Linux_G++_Stdasync - Fatal编程技术网

C++ std::async导致分段错误(或速度慢)

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

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

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];
    }
};
类求解器
{
垫子;
公众:
//以ax1+ax2+ax3..axN=k的形式给出等式(仅系数)
向量求解(Mat和in)
{
mat=in;
ge(mat);
返回(bs(mat));
}
向量求解(Mat和in)
{
mat=标准::移动(in);
ge(mat);
返回(bs(mat));
}
私人:
无效ge(垫和垫)
{
使用li=long int;
对于(lip=0;p=0;i--)
{
双s=0;
对于(li j=i;j
多线程

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];
    }
};
类求解器
{
垫子;
公众:
//以ax1+ax2+ax3..axN=k的形式给出等式(仅系数)
向量求解(Mat和in)
{
mat=in;
ge(mat);
返回(bs(mat));
}
向量求解(Mat和in)
{
mat=标准::移动(in);
ge(mat);
返回(bs(mat));
}
私人:
无效ge(垫和垫)
{
使用li=long int;
对于(lip=0;p=0;i--)
{
双s=0;
对于(li j=i;j
分割正在发生

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)
{
使用li=尺寸t;
断言(a.size()==b.size());
对于(li i=0;i


无论
垫子的类型是什么,我很确定:

auto temp = mat[p];
不创建引用,而是创建副本。就是这个意思

ts.push_back(std::async(std::launch::async, vecSub, std::ref(mat[c]), std::ref(temp)));`
实际上引用了一个临时值
temp
,它将在循环结束时被销毁。这是未定义的行为。
这可能会解决问题:

auto& temp = mat[p];

这就是为什么这个问题在顺序运行时没有发生,但正如你所说的,当它异步运行时,它将超出范围。你的主要解决方案不起作用,因为vecMul()修改原始矩阵,它将给出垃圾值,还有其他想法吗?它仍然崩溃吗?它没有崩溃,我不能使用引用,因为它会改变原始矩阵。它没有bug,但是异步版本要慢得多,如果它不再崩溃(这是最初的问题),那么将其标记为[solved],因为您已经为新问题写了一篇新文章。