【问题标题】:Is it safe to multiply a float/double by 0.5 instead of divide by 2 in C# and C++?在 C# 和 C++ 中将 float/double 乘以 0.5 而不是除以 2 是否安全?
【发布时间】:2012-01-17 03:10:18
【问题描述】:

基本上是这样的(不是真正的代码):

for(int i = 0; i < 1000000000; ++i)
{
     Vert v0 = mesh.polygons[i].edges[0].vert0;
     Vert v1 = mesh.polygons[i].edges[0].vert1;

     Vector3 center = (v0.pos + v1.pos) / 2;
}

v0.pos 的类型为 Vector3&lt;float, float, float&gt;,但也可以是 Vector3&lt;double, double, double&gt;

这样做安全吗?:

Vector3 center = (v0.pos + v1.pos) * 0.5;

这似乎是过早的优化,但它必须尽可能快,才能在数十亿点(点云)上调用。

【问题讨论】:

  • 衡量这两种选择的性能时会发生什么?如果不测量目标平台上的结果,就无法谈论这一级别的优化。
  • 同意格雷格。另外,请记住,您应该在速度之前关注正确性。很多时候,编译器会为你优化大部分内容(尤其是当你使用文字时)。
  • @Chad:我希望不是浮点数。
  • 内存访问将成为那里的瓶颈。在现代硬件上,mul 和 div FP 操作在性能上非常相似。优化可能在 10 年前更有用。
  • 我刚刚测试过了。是的,VC++ 似乎用*.5 替换了/2

标签: c# c++ .net performance optimization


【解决方案1】:

无论如何都不是 C++ 专家,但在 C# 中,这样做:

var a = new Func<float, float, double>((float f1, float f2) => (f1 + f2) * 0.5);
var b = new Func<float, float, double>((float f1, float f2) => (f1 + f2) / 2);

在前者中生成 IL:

  1. 加载参数
  2. 添加它们(生成单个)
  3. 将结果转换为双精度数
  4. 加载双参数 (0.5)
  5. 相乘(产生双倍)
  6. 返回结果

和后者

  1. 加载参数
  2. 添加它们(生成单个)
  3. 加载常量整数 (2)
  4. 除法(产生单,因为单 / 整数产生单)
  5. 将结果转换为双精度数
  6. 返回结果

令我震惊的是,前者可能具有更高的精度,因为乘法是在 2 个双精度上执行的,从而导致双精度,而在后者中,除法是在一个向上转换为双精度的单上执行的(但仍然只会有单的精度)。

这证明了我:

Console.Out.WriteLine(((double)1) * ((double)1/3));
Console.Out.WriteLine((1) / ((float)3));

产生:

0.333333333333333
0.3333333

所以,'安全',也许,如果 失去精度 获得额外的精度 是可以的。

【讨论】:

  • “5. 将结果转换为双精度数”:那些代表Func&lt;float,float,double&gt; 有没有机会?
  • 是的,对不起,我的副本不好...已修复。
  • 确实,很好,但在我看来,问题是关于将除法更改为乘法是否会改变结果(假设两者的输入相同),在这种情况下我不会不知道会怎样。即在除法之前将 (f1+f2) 转换为 double 或将 0.5 转换为 float 并且结果应该相同
  • 它确实改变了结果——这就是我在上面说明的。我有两种具有相同签名的方法,它们都计算两个浮点数之间的平均值。一个使用 (x+y)*0.5,另一个使用 (x+y)/2,它们返回不同精度的数字。这些值在较短的精度下是等效的,是的,但精度在他的用例中可能很重要。
  • 正如我所说,如果您转换值以便除法/乘法使用相同的精度输入,则输出将是相同的。您的大部分帖子都是为了表明您的示例并非如此,所以我假设您误解了我?
猜你喜欢
  • 2011-10-10
  • 1970-01-01
  • 2020-10-11
  • 1970-01-01
  • 2012-12-12
  • 2010-09-10
  • 1970-01-01
  • 1970-01-01
  • 2014-10-20
相关资源
最近更新 更多