这些语句是否等效(静态变量、常量变量和泛型)
Are these statements equivalent (static variables, const variables, and generics)
所以我正在编写一个自定义平滑步骤函数,允许我编辑平滑量。
本质上,对于低因子,平滑步骤实际上是线性的,但对于高因子,有一个很大的曲线。
执行此操作的代码如下:
float smoothstep(float x, float factor) {
float c = 0.5f / ((1.0f / (1.0f + exp(-factor))) - 0.5f);
return c * ((1.0f / (1.0 + exp(-factor * (2.0f * x - 1.0f)))) - 0.5f) + 0.5;
}
现在,由于此方法将在一帧中调用几千次,因此我正在尝试对其进行优化,以便在运行时计算c。我希望编译器可以做到这一点,因为我传递的因素数量有限。因此,传入因子的变量将始终以例如smoothstep(x, 1.0)
编写。到目前为止,我实际上将传递一个因素。
所以我像这样重写了函数以使用泛型参数
template <int F>
float smoothstep(float x) {
const float factor = (float)F / 100.0;
static const float c = 0.5f / ((1.0f / (1.0f + exp(-factor))) - 0.5f);
return c * ((1.0f / (1.0 + exp(-factor * (2.0f * x - 1.0f)))) - 0.5f) + 0.5;
}
这是相当不理想的,因为您只能使用整数作为模板参数,因此我必须传入一个 int,它是我实际需要的 100 倍。话虽如此,我相信这个解决方案将导致编译器预先计算因子和c。
现在我的问题是有没有泛型的方法可以做到这一点,这是我在这次身上采取的两次刺
伤float smoothstep(float x, float factor) {
const float c = 0.5f / ((1.0f / (1.0f + exp(-factor))) - 0.5f);
return c * ((1.0f / (1.0 + exp(-factor * (2.0f * x - 1.0f)))) - 0.5f) + 0.5;
}
和
float smoothstep(float x, float factor) {
static const float c = 0.5f / ((1.0f / (1.0f + exp(-factor))) - 0.5f);
return c * ((1.0f / (1.0 + exp(-factor * (2.0f * x - 1.0f)))) - 0.5f) + 0.5;
}
我希望在其中一个情况下,预编译器(Clang和G ++(看到这些并为我传入的每个有限因子预先计算c。
我的理解是,const
是一个关键字,用于向预编译器和编译器发出变量不会更改的信号,因此它应该考虑对其进行优化。
我还认为,对作用域变量的static
会向编译器建议该变量属于该函数,从而使编译器预先计算它并将其包含在每个因子的函数定义中。
然而,我非常怀疑我对const
和static
的理解是否正确,因此我猜测这些定义都没有预先计算c。我做错了什么?有没有一种非通用的方法可以让预编译器预计算 c?
只需使函数inline
(这也意味着该函数应该在头文件中(并确保进行了优化。
示例:https://godbolt.org/z/rztmWe - 如您所见,只有一个调用exp
。
不幸的是,我认为没有一种保证的方法可以获得这种效果 - 您将不得不依赖编译器优化。另一方面,如今许多编译器优化都相当可靠。
- 用C++中的一个变量定义一个常量
- 通过多个头文件使用常量变量
- 有没有什么方法可以使用一个函数中定义的常量变量,也可以由c++中同一程序中的其他函数使用
- 递归模板化函数不能分配给具有常量限定类型"const tt &"的变量"state"
- 非常量变量只读位置的赋值
- 多个"常量引用"变量可以共享同一个内存吗?
- 使用大量已知常量变量的正确方法
- 常量成员函数中成员变量的类型
- 无法在具有常量变量大小的类中创建堆栈分配数组
- 错误:constexpr 变量'struct2Var'必须由常量表达式初始化
- 这些语句是否等效(静态变量、常量变量和泛型)
- 如何将变量内容常量转换为 std::array 的大小?
- 我应该使我的局部变量常量还是可移动的
- 为什么我可以改变常量对象中的成员变量,这是返回常量对象函数的结果?
- 对全局变量的非常量引用的初始化无效
- 如何在 C++ 中的 wcstok 中使用常量 WCHAR* 变量?
- 将 static_cast<int>(-15) 分配给静态常量字符类型变量
- 全局变量/常量的替代方案
- 为什么首选 if( 常量 == 变量 ) 而不是 if ( 变量 == 常量 )
- 在c++中声明一个变量常量有什么意义