使库函数模板化以避免编译器指令是否有益?
Is it beneficial to make library functions templated to avoid compiler instructions?
假设我正在命名空间l
中创建自己的库。使尽可能多的命名空间成员模板化是否有益?这将鼓励编译器仅为库用户实际调用的成员生成指令。为了明确我的观点,我将在这里演示它:
1)
namespace l{
template <typename = void>
int f() { return 3; }
}
与。
2)
namespace l{
int f() { return 3; }
}
它不是在主要调用以显示差异。
int main() { return EXIT_SUCCESS; }
功能 1) 不需要额外的指令来l::f()
:
main:
push rbp
mov rbp, rsp
mov dword ptr [rbp - 4], 0
mov eax, 0
pop rbp
ret
函数 2) 确实需要额外的指令才能l::f()
(如果再次未调用l::f()
):
l::f()
push rbp
mov rbp, rsp
mov eax, 3
pop rbp
ret
main:
push rbp
mov rbp, rsp
mov dword ptr [rbp - 4], 0
mov eax, 0
pop rbp
ret
tl;博士
使库函数模板化以避免编译器指令是否有益?
不。发出死代码并不是编译的昂贵部分。文件访问,解析和优化(不一定按此顺序)需要时间,这个想法迫使库客户端读取和解析比常规标头+库模型更多的代码。
模板通常被指责为减慢构建速度,而不是加快构建速度。
这也意味着您无法提前构建库,因此每个用户都需要在使用它们的每个翻译单元中从头开始编译他们使用的任何部分。
使用模板化版本,编译所花费的总时间可能会更长。您必须分析才能确定(我怀疑这个f
太小了,以至于无论哪种方式都是无法估量的),但我很难将其视为有用的改进。
无论如何,您的比较并不具有代表性 - 一个好的编译器会在链接时丢弃死代码。有些还可以从静态库中内联代码,因此对编译时或运行时性能没有可靠影响。
相关文章:
- 存储指令是否会阻止缓存未命中的后续指令?
- 是否有用于元素部分移位的 simd 指令/内在/内置指令?
- 使用预处理指令检查是否包含标头?
- C++11:16 字节原子<>变量是否在 16 字节边界上自动对齐,从而允许CMPXCHG16B指令?
- 是否启用了 SSE2 指令?
- 在给定时间段内,线程执行的指令数量是否有最小数量?
- 是否可以转换预处理器指令中的字符?
- 睡眠线程或进程的指令是否在线程/进程休眠时继续执行?
- 是否可以使用模板非类型参数使用#if指令?(矢量多合一类)
- 使库函数模板化以避免编译器指令是否有益?
- 如何检查编译的代码是否使用了 SSE 和 AVX 指令?
- 使用原子指令确保映射访问安全,是否可以使用两个不同的原子对指令进行重新排序
- 是否可以将 GCC 配置为忽略 #pragma 指令
- 如何验证 LLVM "ret"指令是否返回 void?
- 是否有一种方法可以将变量列表传递给#Define指令,并导致其通过文字值替换字符串值
- MOV x86指令是否实现C++11 memory_order_release原子存储
- 是否有任何预处理器指令控制循环展开
- 是否所有使用指令的方式与使用命名空间std的方式相同
- 确定指令是否具有间接内存操作数
- 在展开宏之前是否处理了预处理器指令