gpt4 book ai didi

c++ - 通过 const 引用传递基本值真的会损害性能吗?

转载 作者:太空狗 更新时间:2023-10-29 20:08:26 25 4
gpt4 key购买 nike

我正在编写一个进行数值计算的库。我正在使用模板,以便最终用户可以选择他们想要的精度。我希望它能同时处理基本类型(doublefloat)和高精度类类型(例如 boost::multiprecision)。我想知道参数类型应该是 T 还是 const & T

在 SO/google 上有很多关于按值传递与按引用传递的帖子。 “经验法则”之一似乎是:

  • 按值传递基本类型
  • 通过 const 引用传递其他所有内容

但是,如果您有模板,这会变得困惑:

template<typename T>
T doSomething(T x, T y)
{
return x + y;
}

对比

template<typename T>
T doSomething(const T & x, const T & y)
{
return x + y;
}

对于 boost::multiprecision,您几乎肯定希望通过 const 引用传递。问题是通过 const & 传递 double 是否比通过值传递更糟糕。许多 SO 答案都说 const & “没有更好,也许更糟”......但我找不到任何好的硬引用。

我做了以下 benchmark

这似乎表明没有区别,尽管这可能取决于函数的简单性和内联行为。

有可能做这样的事情:

#include <type_traits>

template<typename T>
using choose_arg_type =
typename std::conditional<std::is_fundamental<T>::value,
T,
const T &>::type;

template <typename T>
T someFunc(choose_arg_type<T> arg)
{
return arg + arg;
}

int main()
{
auto result = someFunc<double>(0.0);

return 0;
}

但如果它没有带来任何好处,它会增加复杂性并且您会失去类型推导 ( Any way to fix this type deduction? )

我认为通过 const 引用传递速度较慢的一个原因是,如果它确实在使用引用,则可能存在缓存局部性问题。但是,如果编译器只是针对值进行优化……这无关紧要。

处理此问题的最佳方法是什么?

最佳答案

至少在一种情况下,传递 const 引用可能会禁用优化。但是,最流行的编译器提供了一种重新启用它们的方法。

让我们看看这个函数:

int cryptographicHash( int& salt, const int& plaintext )
{
salt = 4; // Chosen by fair dice roll
// guaranteed to be random
return plaintext; // If we tell them there's a salt,
// this is the last hash function they'll
// ever suspect!
}

看起来很安全,对吧?但是,由于我们是用 C++ 编写的,它是否尽可能快? (绝对是我们想要的加密哈希。)

不,因为如果你调用它会怎样:

int x = 0xFEED;
const int y = cryptographicHash( x, x );

现在通过引用传递的参数别名是同一个对象,所以函数应该像写的那样返回 4,而不是 0xFEED。这意味着,灾难性的是,编译器无法再优化其 const int& 参数中的 &

但是,最流行的编译器(包括 GCC、clang、Intel C++ 和 Visual C++ 2015 and up)都支持 __restrict 扩展。因此,将函数签名更改为 int cryptographicHash( int& salt, const int& __restrict plaintext ),所有问题都将永远解决。

由于此扩展不是 C++ 标准的一部分,您可以通过以下方式提高可移植性:

#if ( __GNUC__ || __clang__ || __INTEL_COMPILER || __ICL || _MSC_VER >= 1900 )
# define RESTRICT __restrict
#else
# define RESTRICT /**/
#endif

int cryptographicHash( int& salt, const int& RESTRICT plaintext );

(在 GCC 和 clang 中,这似乎不会更改生成的代码。)

关于c++ - 通过 const 引用传递基本值真的会损害性能吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54151289/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com