我正在同时学习C++和OpenCV。我正在阅读以下内容,这一点尚不清楚,为什么按值传递参数通常会使编译器的代码优化更加容易。


void salt(Mat image, int n)
{
    default_random_engine generator;
    uniform_int_distribution<int> randomRow(0, image.rows - 1);
    uniform_int_distribution<int> randomCol(0, image.cols - 1);

    for (int k = 0; k < n; k++)
    {
        int i = randomCol(generator);
        int j = randomRow(generator);

        if (image.type() == CV_8UC1)
            image.at<uchar>(j, i) = 255;
        else if (image.type() == CV_8UC3)
            image.at<Vec3b>(j, i) = Vec3b(255, 0, 0);
    }
}

最佳答案

用两个词表示:别名分析。请记住,(例如)const int &r不会将r声明为对不变的整数的引用,而是对不可用于对其进行更改的整数的引用。因此,只要对int的引用写入任何内容,就必须重新加载r的值,并且不会发生常见的子表达式消除和代码移动。如果r是本地r 对象,则编译器通常可以证明其地址永不转义;否则,编译器将继续执行该操作。那么它就可以忽略对其他任何内容的写操作,通常允许int保留在寄存器中或尽早丢弃。

这在您引用的段落中被放在一边,因为在所讨论的情况下它不太重要:r必须包含指向基础图像数据的指针,因此即使Mat通过值传递,也可能会出现别名。 (能够证明有关指针本身的东西可能会带来一些好处,但必须以牺牲引用计数或类似费用为代价。)

10-06 11:16