使用 tbb::parallel_invoke 时导致段错误的原因是什么?
What cause segmentation fault error when using tbb::parallel_invoke?
我尝试在 ubuntu 18.04 上同时使用 openmp 和 intel tbb 以及 gcc 和 g++ 版本 6 来优化我的代码。我使用 openmp 优化 for
循环和 tbb::parallel_invoke
到 运行 1 个具有 4 个不同输入的函数。
我尝试使用 lambda 表达式通过引用传递一些参数,但我不确定我是否写对了。但是,我在使用 parallel_invoke.
时不断收到 "segmentation fault (core dumped)" 错误
int shrink = 6;
cv::Mat mat1, mat2;
tbb::parallel_invoke([&]
{mat1 = myfunction(image1, arg1, arg2) * shrink;}, [&]
{mat2 = myfunction(image2, arg1, arg2) * shrink;});
image1、image2、arg1是opencv矩阵,arg2是我自己定义的class。
当我运行没有并行化的程序
mat1 = myfunction(image1, arg1, arg2) * shrink;
mat2 = myfunction(image2, arg1, arg2) * shrink;
没有问题,程序运行很好。我使用 parallel_invoke 因为我希望这两个可以同时是 运行。它不工作是因为同时使用了 arg1 和 arg2 吗?
我不知道该怎么做,因为 Segmentation fault (core dumped)
是终端中显示的全部内容。
编辑:
这就是 Myfunction() 的样子:
Mat edgebox_main(Mat E0, Mat O0, _para o) {
// check and get inputs
arrayf E;
arrayf O;
int h = E0.rows;
O._h = E._h = h;
int w = E0.cols;
O._w = E._w = w;
E._x = new float[h * w];
O._x = new float[h * w];
getadd(E0, E._x);
getadd(O0, O._x);
//optionally create memory for visualization
arrayf V;
// setup and run EdgeBoxGenerator
EdgeBoxGenerator edgeBoxGen;
Boxes boxes;
edgeBoxGen._alpha = o.alpha;
edgeBoxGen._beta = o.beta;
edgeBoxGen._eta = o.eta;
edgeBoxGen._minScore = o.minScore;
edgeBoxGen._maxBoxes = o.maxBoxes;
edgeBoxGen._edgeMinMag = o.edgeMinMag;
edgeBoxGen._edgeMergeThr = o.edgeMinMag;
edgeBoxGen._clusterMinMag = o.clusterMinMag;
edgeBoxGen._maxAspectRatio = o.maxAspectRatio;
edgeBoxGen._minBoxArea = o.minBoxArea;
edgeBoxGen._maxBoxLength = std::min(std::min((int)o.maxBoxLength,h),w);
edgeBoxGen._gamma = o.gamma;
edgeBoxGen._kappa = o.kappa;
edgeBoxGen.generate(boxes, E, O, V);
boxesNms(boxes,edgeBoxGen._beta,edgeBoxGen._eta,edgeBoxGen._maxBoxes);
// create output bbs and output to Matlab
int n = (int) boxes.size();
float *bbs = new float[n * 5];
for (int i = 0; i < n; i++) {
bbs[i + 0 * n] = (float) boxes[i].c + 1;
bbs[i + 1 * n] = (float) boxes[i].r + 1;
bbs[i + 2 * n] = (float) boxes[i].w;
bbs[i + 3 * n] = (float) boxes[i].h;
bbs[i + 4 * n] = boxes[i].s;
}
Mat bbs_mat(n, 5, CV_32FC1);
fillmat(bbs, bbs_mat);
return bbs_mat;
}
该代码调用了其他几个 class 和函数,如果我将它们全部写在这里,我认为它们会太长。此外,我在 Linux 中的调试方面也不是很有经验。我通常使用 Microsoft Visual Studio 来调试 C++,所以我真的不知道如何在终端中生成额外的调试信息,您对使用什么调试器有什么建议吗?或者仅 g++ 就足够了吗?
在我使用堆栈跟踪并检查核心转储后,如post中所写。我收到其他错误消息,其中显示 SIGSEGV 错误。该错误基本上表明我试图访问数组中不可用的元素。
我尝试在 ubuntu 18.04 上同时使用 openmp 和 intel tbb 以及 gcc 和 g++ 版本 6 来优化我的代码。我使用 openmp 优化 for
循环和 tbb::parallel_invoke
到 运行 1 个具有 4 个不同输入的函数。
我尝试使用 lambda 表达式通过引用传递一些参数,但我不确定我是否写对了。但是,我在使用 parallel_invoke.
时不断收到 "segmentation fault (core dumped)" 错误int shrink = 6;
cv::Mat mat1, mat2;
tbb::parallel_invoke([&]
{mat1 = myfunction(image1, arg1, arg2) * shrink;}, [&]
{mat2 = myfunction(image2, arg1, arg2) * shrink;});
image1、image2、arg1是opencv矩阵,arg2是我自己定义的class。
当我运行没有并行化的程序
mat1 = myfunction(image1, arg1, arg2) * shrink;
mat2 = myfunction(image2, arg1, arg2) * shrink;
没有问题,程序运行很好。我使用 parallel_invoke 因为我希望这两个可以同时是 运行。它不工作是因为同时使用了 arg1 和 arg2 吗?
我不知道该怎么做,因为 Segmentation fault (core dumped)
是终端中显示的全部内容。
编辑: 这就是 Myfunction() 的样子:
Mat edgebox_main(Mat E0, Mat O0, _para o) {
// check and get inputs
arrayf E;
arrayf O;
int h = E0.rows;
O._h = E._h = h;
int w = E0.cols;
O._w = E._w = w;
E._x = new float[h * w];
O._x = new float[h * w];
getadd(E0, E._x);
getadd(O0, O._x);
//optionally create memory for visualization
arrayf V;
// setup and run EdgeBoxGenerator
EdgeBoxGenerator edgeBoxGen;
Boxes boxes;
edgeBoxGen._alpha = o.alpha;
edgeBoxGen._beta = o.beta;
edgeBoxGen._eta = o.eta;
edgeBoxGen._minScore = o.minScore;
edgeBoxGen._maxBoxes = o.maxBoxes;
edgeBoxGen._edgeMinMag = o.edgeMinMag;
edgeBoxGen._edgeMergeThr = o.edgeMinMag;
edgeBoxGen._clusterMinMag = o.clusterMinMag;
edgeBoxGen._maxAspectRatio = o.maxAspectRatio;
edgeBoxGen._minBoxArea = o.minBoxArea;
edgeBoxGen._maxBoxLength = std::min(std::min((int)o.maxBoxLength,h),w);
edgeBoxGen._gamma = o.gamma;
edgeBoxGen._kappa = o.kappa;
edgeBoxGen.generate(boxes, E, O, V);
boxesNms(boxes,edgeBoxGen._beta,edgeBoxGen._eta,edgeBoxGen._maxBoxes);
// create output bbs and output to Matlab
int n = (int) boxes.size();
float *bbs = new float[n * 5];
for (int i = 0; i < n; i++) {
bbs[i + 0 * n] = (float) boxes[i].c + 1;
bbs[i + 1 * n] = (float) boxes[i].r + 1;
bbs[i + 2 * n] = (float) boxes[i].w;
bbs[i + 3 * n] = (float) boxes[i].h;
bbs[i + 4 * n] = boxes[i].s;
}
Mat bbs_mat(n, 5, CV_32FC1);
fillmat(bbs, bbs_mat);
return bbs_mat;
}
该代码调用了其他几个 class 和函数,如果我将它们全部写在这里,我认为它们会太长。此外,我在 Linux 中的调试方面也不是很有经验。我通常使用 Microsoft Visual Studio 来调试 C++,所以我真的不知道如何在终端中生成额外的调试信息,您对使用什么调试器有什么建议吗?或者仅 g++ 就足够了吗?
在我使用堆栈跟踪并检查核心转储后,如post中所写。我收到其他错误消息,其中显示 SIGSEGV 错误。该错误基本上表明我试图访问数组中不可用的元素。