我正在开发一些工程模拟。这需要实现一些长方程式,比如这个方程式来计算橡胶类材料的应力:
T = (
mu * (
pow(l1 * pow(l1 * l2 * l3, -0.1e1 / 0.3e1), a) * a
* (
pow(l1 * l2 * l3, -0.1e1 / 0.3e1)
- l1 * l2 * l3 * pow(l1 * l2 * l3, -0.4e1 / 0.3e1) / 0.3e1
) * pow(l1 * l2 * l3, 0.1e1 / 0.3e1) / l1
- pow(l2 * pow(l1 * l2 * l3, -0.1e1 / 0.3e1), a) * a / l1 / 0.3e1
- pow(l3 * pow(l1 * l2 * l3, -0.1e1 / 0.3e1), a) * a / l1 / 0.3e1
) / a
+ K * (l1 * l2 * l3 - 0.1e1) * l2 * l3
) * N1 / l2 / l3
+ (
mu * (
- pow(l1 * pow(l1 * l2 * l3, -0.1e1 / 0.3e1), a) * a / l2 / 0.3e1
+ pow(l2 * pow(l1 * l2 * l3, -0.1e1 / 0.3e1), a) * a
* (
pow(l1 * l2 * l3, -0.1e1 / 0.3e1)
- l1 * l2 * l3 * pow(l1 * l2 * l3, -0.4e1 / 0.3e1) / 0.3e1
) * pow(l1 * l2 * l3, 0.1e1 / 0.3e1) / l2
- pow(l3 * pow(l1 * l2 * l3, -0.1e1 / 0.3e1), a) * a / l2 / 0.3e1
) / a
+ K * (l1 * l2 * l3 - 0.1e1) * l1 * l3
) * N2 / l1 / l3
+ (
mu * (
- pow(l1 * pow(l1 * l2 * l3, -0.1e1 / 0.3e1), a) * a / l3 / 0.3e1
- pow(l2 * pow(l1 * l2 * l3, -0.1e1 / 0.3e1), a) * a / l3 / 0.3e1
+ pow(l3 * pow(l1 * l2 * l3, -0.1e1 / 0.3e1), a) * a
* (
pow(l1 * l2 * l3, -0.1e1 / 0.3e1)
- l1 * l2 * l3 * pow(l1 * l2 * l3, -0.4e1 / 0.3e1) / 0.3e1
) * pow(l1 * l2 * l3, 0.1e1 / 0.3e1) / l3
) / a
+ K * (l1 * l2 * l3 - 0.1e1) * l1 * l2
) * N3 / l1 / l2;
我使用 Maple 来生成 C + + 代码,以避免错误(并节省繁琐的代数时间)。由于此代码执行了数千次(如果不是数百万次) ,因此性能是一个问题。不幸的是,数学到目前为止只是简化了,长长的等式是不可避免的。
我可以采取什么方法来优化这个实现?我正在寻找在实现这些方程时应该采用的高级策略,而不一定是针对上面示例的具体优化。
我用 g + + 和 --enable-optimize=-O3
编译。
更新:
我知道有很多重复的表达式,我假设编译器会处理这些; 到目前为止,我的测试表明它会处理这些。
l1, l2, l3, mu, a, K
都是正实数(不是零)。
我已经将 l1*l2*l3
替换为一个等效的变量: J
。这确实有助于提高性能。
用 cbrt(x)
代替 pow(x, 0.1e1/0.3e1)
是一个很好的建议。
这将运行在 CPU 上,在不久的将来,这可能会更好地运行在 GPU 上,但现在这个选项是不可用的。