我有以下代码
void Fun2()
{
if(X<=A)
X=ceil(M*1.0/A*X);
else
X=M*1.0/(M-A)*(M-X);
}
我想使用C99快速编程,考虑以下注释。
X
和A
是32位变量,我将其声明为uint64_t
,而M
为static const uint64_t
。
此函数由另一个函数调用,A
的值每n
次调用一次更改为新值。
执行时需要优化,CPU是Core i3,OS是windows 7
我想实现的数学模型是
F=ceil(Max/A*X) if x<=A
F=floor(M/(M-A)*(M-X)) if x>A
为了清晰而没有混淆我以前的帖子是 我有以下代码
void Fun2()
{
if(X0<=A)
X0=ceil(Max1*X0);
else
X0=Max2*(Max-X0);
}
我想使用C99快速编程,考虑以下注释。
X0,A,Max1和Max2是32位变量,我将它们声明为uint64_t,而Max则表示为静态const uint64_t。
此函数由另一个函数调用,Max1,A,Max2的值每n次调用后更改为随机值。
我在Windows 7和codeblocks软件中工作
由于
答案 0 :(得分:3)
在没有特定目标的情况下优化这样的代码是完全没有意义的,也是不可能的。为此,您需要以下知识:
在不知道上述情况的情况下,您可以做的唯一一种优化是在算法级别上。发布的代码中没有这样的算法。
因此,在提供更多信息之前,任何人都无法回答您的问题。
答案 1 :(得分:0)
如果“快速方式”意味着快速执行,那么您的第一个更改就是将此功能声明为内联版本,这是C99的一项功能。
inline void Fun2()
{
...
...
}
我记得GNU CC有一些有趣的宏可能有助于优化这些代码。我认为这不符合C99,但总是很有趣。我的意思是:你的函数有一个if语句。如果您可以提前了解每个分支的可能性,您可以执行以下操作:
if (likely(X0<=A)).....
如果X0可能小于或等于A.或者:
if (unlikely(X0<=A)).....
如果X0不可能小于或等于A。
有了这些信息,编译器将优化比较和跳转,这样最可能的分支将在没有跳转的情况下执行,因此它将在没有分支预测的架构中更快地执行。
可以提高速度的另一件事是使用?:三元运算符,因为两个分支都为同一个变量赋值,如下所示:
inline void Func2()
{
X0 = (X0>=A)? Max1*X0 : Max2*(Max-X0);
}
BTW:为什么要使用ceil()
? ceil()
用于将二进制数向下舍入为最接近的非整数。如果X0
和Max1
是整数,则结果中不会有小数,因此ceil()
不会产生任何影响。
答案 2 :(得分:0)
我认为可以改进的一件事就是不使用浮点数。你的代码主要处理整数,所以你想坚持整数运算。
唯一的浮点数是Max1
。如果它总是完整的,它可以是整数。如果没有,您可以用两个整数替换它:Max1*X0
- &gt; X0 * Max1_nom / Max1_denom
。如果你计算一次指数/分母,并多次使用,这可以加快速度。
答案 3 :(得分:0)
我将数学模型转换为
Ceil (M*(X-0) / (A-0)) when A<=X
Floor (M*(X-M) / (A-M)) when A>X
与
Ceil (A / B) = Floor((A + (B-1)) / B)
替换为第一个给出:
((M * (X - m0) + c ) / ( A - m0))
,其中
c = A-1; m0 = 0, when A <= X
c = 0; m0 = M, when A >= X
所有内容都将以整数运算方式执行,但提前计算倒数非常困难;
可能仍然可以使用某种形式的DDA来避免计算迭代之间的划分。
使用临时常量c,m0仅用于统一两个分支的管道,因为下一步是追求并行性。