常数除以未优化?

时间:2015-10-08 22:40:35

标签: c optimization divide

我有以下代码行:

library(lpSolveAPI)

# Defines the 'score' which we seek to maximize
mat <- data.frame(score = c(0.04, 0.04, -.11, -.03, 0.04, 0.04, -0.06, 0.01))

# Side specifies whether something is a 'sell' or a 'buy'
mat[, 'side'] <- c(1, 1, -1, -1, 1, 1, -1, -1)

# 'a' and 'b' are descriptive factors defining what something is thing a or thing b. 
mat[, 'a'] <- c(1, 1, 1, 1, 0, 0, 0, 0)
mat[, 'b'] <- c(0, 0, 0, 0, 1, 1, 1, 1)


# the lower bound for all sides = -1 have a lower bound of some negative value and an upper bound of zero
mat[, "lb"] <- c(0, 0, -0.2, -0.4, 0, 0, -.1, -.2)
# the upper bound for all sides = 1 have a lower bound of zero and an upper bound of 1
mat[, 'ub'] <- c(1, 1, 0, 0, 1, 1, 0, 0)
# this is just initializing our variables field which will be populated later
mat[, 'x'] <- rep(0, 8)


# using the lpSolveAPI package, create a program with the number of rows in the matrix 'mat'
LP <- make.lp(0, nrow(mat))

set.objfn(LP, -mat[, 'score'])
set.bounds(LP, lower = mat[, 'lb'])
set.bounds(LP, upper = mat[, 'ub'])

# This constraint requires that the sum of all of x must be equal to zero. In other words, the amount of sells equals the amount of buys
add.constraint(LP, rep(1, nrow(mat)), "=", 0)

solve(LP)
get.objective(LP)
get.variables(LP)

mat$x <- get.variables(LP)

我的编译器(在这种情况下,Windriver DIAB PPC,使用标准的扩展优化设置-XO)似乎并没有将其优化为类似temp = s16_myvar的东西。当我查看汇编列表时,它似乎忠实地将360放入寄存器中,然后在进行乘法后,将结果除以360.

我可以使用哪种技巧可以消除最终代码中的乘法和除法?

对于那些问你,为什么?&#34;,假设在某些配置中,B不是== A,你需要缩放变量。

4 个答案:

答案 0 :(得分:2)

只是一个假设:当(a x) / b(a / b) xb没有溢出时,a之类的整数表达式可以简化为a x。可能是优化器设计者没有那么深入,或者认为这样的表达式不太可能/愚蠢。

<强>更新

在Olaf发表评论之后,溢出条件无关紧要,因为它是一种未定义的行为,因此运行时可以自由返回任何值。

答案 1 :(得分:1)

让16位变量s16_myvar签名为32700.假设A和B是完全正常的32位有符号整数,如360000。

然后将变量提升为int,并进行乘法运算,得到11,772,000,000,其回绕到-1,112,901,888。

除以B,你得到-3091。

这就是你想要的吗?您可能知道这些数字不会被包围,但编译器无法承担它。

答案 2 :(得分:0)

我将尝试使用此函数形式作为可能的解决方案。我的想法是,如果注意到scale_a和scale_b是相同的,编译器可以优化大多数指令。我会回复我的结果。

__inline__ S16 RESCALE_FUNC(short s16_input, const short *scale_a, const short *scale_b)
{
    return (scale_a==scale_b)?(s16_input):((s16_input*(*scale_a))/(*scale_b));
}   

temp = RESCALE_FUNC(s16_myvar, A, B);

答案 3 :(得分:0)

这对我来说是个好行为。评估订单很重要。 假设您正在进行定点运算(或任何常规整数运算),并且您想要计算“输入中的输出= 80%”。 然后你做:输出=(输入* 80)/ 100; 让我们假设输入= 201。 如果编译器决定先做80/100: 输出= 201 *(80/100)= 201 * 0 = 0。 这是因为80和100是整数(同样适用于int变量)。

但是既然你明确地添加了一些括号,那么你得到: 输出=(输入* 80)/ 100 =(201 * 80)/ 100 = 16080/100 = 160。

在那里,160是201的“大约”80%(记住,我们使用的是整数而不是浮点数。)

相关问题