简单的数学运算在double上比在float数据类型上更快? [英] Simple math operations faster on double than on float datatype?

查看:99
本文介绍了简单的数学运算在double上比在float数据类型上更快?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


可能重复:

我编写了简单的基准测试来检查我的应用程序中将 double 数据类型更改为 float 可以获得多少性能。这是我的代码:

I wrote simple benchmark to check how much performance i can get changing double datatype to float in my application. Here is my code:

    // my form: 
    // one textbox: textbox1 (MultiLine property set to true)
    // one button: button1 with event button1_Click

    private void button1_Click(object sender, EventArgs e)
    {

        int num = 10000000;

        float[] floats1 = new float[num];
        float[] floats2 = new float[num];
        float[] floatsr = new float[num];  // array for results
        double[] doubles1 = new double[num];
        double[] doubles2 = new double[num];
        double[] doublesr = new double[num]; // array for results

        Stopwatch stw = new Stopwatch();

        log("Preparing data");

        Random rnd = new Random();

        stw.Start();

        for (int i = 0; i < num; i++)
        {
            floats1[i] = NextFloat(rnd);
            floats2[i] = NextFloat(rnd);
            doubles1[i] = rnd.NextDouble();
            doubles2[i] = rnd.NextDouble();
        }
        stw.Stop();
        log(stw.Elapsed.TotalMilliseconds.ToString()+"ms");
        stw.Reset();




        log("");


        stw.Start();
        for (int i = 0; i <# i++)
        {
            floatsr[i] = floats1[i] * floats2[i];
        }
        stw.Stop();
        log("Multiplying floats: " + stw.Elapsed.TotalMilliseconds.ToString() + "ms");
        stw.Reset();



        stw.Start();
        for (int i = 0; i < num; i++)
        {
            doublesr[i] = doubles1[i] * doubles2[i];
        }
        stw.Stop();
        log("Multiplying doubles: " + stw.Elapsed.TotalMilliseconds.ToString() + "ms");
        stw.Reset();


        stw.Start();
        for (int i = 0; i < num; i++)
        {
            floatsr[i] = floats1[i] / floats2[i];
        }
        stw.Stop();
        log("Dividing floats: " + stw.Elapsed.TotalMilliseconds.ToString() + "ms");
        stw.Reset();


        stw.Start();
        for (int i = 0; i < num; i++)
        {
            doublesr[i] = doubles1[i] / doubles2[i];
        }
        stw.Stop();
        log("Dividing doubles: " + stw.Elapsed.TotalMilliseconds.ToString() + "ms");
        stw.Reset();

    }

    private void log(string text)
    {
        textBox1.Text = textBox1.Text + text + Environment.NewLine;
    }

    // I found that function somewhere on stackoverflow
    static float NextFloat(Random random)
    {
        double mantissa = (random.NextDouble() * 2.0) - 1.0;
        double exponent = Math.Pow(2.0, random.Next(-126, 128));
        return (float)(mantissa * exponent);
    }

我得到了这样的结果(发布,未调试,Intel Mobile Core Duo T2500 2.0GHz 2MB CPU):

I got results like this (release, no debug, Intel Mobile Core Duo T2500 2.0GHz 2MB CPU):

Preparing data 5275,6862ms

Multiplying floats: 442,7865ms 
Multiplying doubles: 169,4028ms
Dividing floats: 550,7052ms 
Dividing doubles: 164,1607ms

我很惊讶,在 double 上的操作比在 float 。我在这里搜索双浮点数,发现了这一点:

I was suprised, that operations on double are almost 3 times faster than operations on float. I searched for "double float" here, and i found this:

Is using double faster than float?

最佳答案集中在CPU架构上,但我不同意。

Best answer is focused on CPU architecture, but I cant agree with that.

我怀疑还有其他原因导致浮点运算性能降低,因为带有Intel SSE的CPU应该能够一次乘以或除以4个浮点运算(打包的浮点指令) ,或一次翻两番。因此,浮点数应该更快。

I suspect that something else is causing low performance on floats, because my CPU with Intel SSE should be able to multiply or divide 4 floats at once (packed floating point instructions), or 2 doubles at once. So floats should be faster.

也许编译器(或.net中的clr)正在以某种方式优化内存使用?

Maybe compiler (or clr in .net) is optimizing memory usage somehow?

有什么方法可以优化它并使浮动速度更快?

请不要报告重复,我看到了其他问题,并且他们不满意我。

更改生成浮点方法后的结果现在看起来不错(由Servy建议) ):

My results after changing method for generating floats now look fine (suggested by Servy):

Preparing data 1367,0678ms

Multiplying floats: 109,8742ms 
Multiplying doubles: 149,9555ms
Dividing floats: 167,0079ms 
Dividing doubles: 168,6821ms


推荐答案

与生成随机数的方式有关。乘和除浮点数并不完全相同;这些数字的实际值很重要。对于浮点数,您要在相当大的范围内填充值。如果您创建的浮点数介于0和1之间,就像双精度数一样,那么结果就会更像您期望的那样。只需将 NextFloat 更改为:

It has to do with how you generated the random numbers. Multiplying and dividing floating point numbers are not all the same; the actual values of those numbers matter. In the case of floats, you're populating a value over a fairly large range. If you create your floats such that they are between 0 and 1, just like the doubles, then it comes out more like you'd expect. Just change NextFloat to be this:

static float NextFloat(Random random)
{
    return (float) random.NextDouble();
}

我刚刚进行了一些测试,但随着更改,浮点数为33%

I just ran a few tests, and with that change the floats were 33% faster at multiplication.

当然,这只是使比较公平的最简单方法。为了更好地了解浮点数与双精度值的实际比较,您希望生成随机浮点数,并在相应类型的整个范围之间或者在更好的情况下,将每个双精度值加倍,这两个保持值都表示程序将使用的数据类型。

Of course, this is just the easiest way to make the comparison "fair". To get a better understanding of how floats really compare to doubles you'd want to generate random floats and doubles each between the full range of the respective types, or better yet, both holding values representing the type of data your program will be using.

这篇关于简单的数学运算在double上比在float数据类型上更快?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆