我想在C中编写函数,需要几秒和几纳秒作为输入。将秒和纳秒转换为微秒,以微秒为单位返回总数。
unsigned long long get_microseconds(int seconds, unsigned long long nSeconds);
现在转换非常简单。我可以使用以下公式 -
mSeconds =秒* 1000000 + nSeconds / 1000(纳秒转换的精度损失没问题,我的计时器无论如何最小分辨率为100微秒)
如果不使用乘法和除法运算符来获得最佳精度和最小数量的cpu周期,那么实现此等式的最快方法是什么。
编辑:我正在使用基于GNU但定制设计的工具链的自定义DSP上运行。我还没有真正测试过算术运算的性能,我只是想知道它是否会影响性能,是否有办法改进它。
答案 0 :(得分:6)
return Seconds*1000000 + nSeconds/1000;
如果有任何有价值的位移或其他位操作值得做,你的编译器可能会处理它。
答案 1 :(得分:1)
编译器几乎肯定会尽可能地优化乘法。它不所做的是"接受一个小损失"当除以1000时,你或许会更快地写
return Seconds*1000000 + nSeconds/1024; /* Explicitly show the error */
...请注意nSeconds
不能增长太多,否则错误可能会变得无法接受。
但无论你做什么,测试结果 - 速度和准确性都超过实际输入。还要探索将函数转换为宏并完全保存调用。坦率地说,对于如此简单的计算,没有比优化编译器更好的机会了。
另外,请考虑全局算法范围内此优化的权重。这个函数真的被调用的频率是its savings are worth the hassle吗?
答案 2 :(得分:0)
如果nSeconds
永远不会超过2 32 (如果你从timespec
开始使用“分割时间”则不应该 - 它应该低于10 9 ),你应该使用32位整数。
在64位机器it's not a problem上使用64位整数(除法优化为multiply by inverse+shift),但在32位编译器上gets tricked into using a full 64 bit division routine,这是相当重量级。所以,我会这样做:
unsigned long long get_microseconds(int seconds, unsigned long nSeconds) {
return seconds*1000000ULL + nSeconds / 1000;
}
这至少在x86上doesn't call external routines,并设法将64位开销保持在最低限度。
当然,这些都是在x86上完成的测试(即使在32位模式下也有32x32 => 64乘法指令),假设您正在使用DSP,则需要检查编译器生成的实际代码