Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/280.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/.htaccess/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在C中,一个浮点乘法需要多少个循环#_C#_Benchmarking_Flops - Fatal编程技术网

C# 在C中,一个浮点乘法需要多少个循环#

C# 在C中,一个浮点乘法需要多少个循环#,c#,benchmarking,flops,C#,Benchmarking,Flops,我有一个数字密集型应用程序,在互联网上寻找GFLOP后,我决定做我自己的小基准测试。我只是做了数千次单线程矩阵乘法,以获得大约一秒钟的执行时间。这是内环。满 for (int i = 0; i < SIZEA; i++) for (int j = 0; j < SIZEB; j++) vector_out[i] = vector_out[i] + vector[j] * matrix[i, j]; for(int i=0;i

我有一个数字密集型应用程序,在互联网上寻找GFLOP后,我决定做我自己的小基准测试。我只是做了数千次单线程矩阵乘法,以获得大约一秒钟的执行时间。这是内环。满

for (int i = 0; i < SIZEA; i++)
    for (int j = 0; j < SIZEB; j++)
        vector_out[i] = vector_out[i] + vector[j] * matrix[i, j];
for(int i=0;i
我已经有好几年没有处理过翻牌了,所以我希望每次翻牌能有3到6个周期。但我得到了30(100 mFLOP),当然,如果我将其并行化,我会得到更多,但我只是没有预料到。这可能是网络的问题吗。或者这真的是CPU性能

下面是一个包含完整基准代码的示例


编辑:VisualStudio即使在发布模式下运行也需要更长的时间,可执行文件本身以12个周期/次浮点(250 MFLOPS)运行。还有虚拟机的影响吗?

您的基准并不是真正测量触发器,它执行一些浮点运算和C#中的循环

但是,如果您可以将代码隔离为浮点操作的重复,那么仍然存在一些问题

您的代码应该包含一些“预循环”,以允许“抖动预热”,因此您不需要测量编译时间

那么,即使你这么做,

您需要在发布模式下进行编译,并在已知的一致性平台上从命令行执行测试


这是我的替代基准

using System;
using System.Linq;
using System.Diagnostics;

class Program
{
    static void Main()
    {
        const int Flops = 10000000;
        var random = new Random();
        var output = Enumerable.Range(0, Flops)
                         .Select(i => random.NextDouble())
                         .ToArray();
        var left = Enumerable.Range(0, Flops)
                         .Select(i => random.NextDouble())
                         .ToArray();
        var right = Enumerable.Range(0, Flops)
                         .Select(i => random.NextDouble())
                         .ToArray();

        var timer = Stopwatch.StartNew();
        for (var i = 0; i < Flops - 1; i++)
        {
            unchecked
            {
                output[i] += left[i] * right[i];
            }
        }

        timer.Stop();
        for (var i = 0; i < Flops - 1; i++)
        {
            output[i] = random.NextDouble();
        }

        timer = Stopwatch.StartNew();
        for (var i = 0; i < Flops - 1; i++)
        {
            unchecked
            {
                output[i] += left[i] * right[i];
            }
        }

        timer.Stop();

        Console.WriteLine("ms: {0}", timer.ElapsedMilliseconds);
        Console.WriteLine(
            "MFLOPS: {0}",
            (double)Flops / timer.ElapsedMilliseconds / 1000.0);
    }
}

注意,我不得不大幅增加操作数以超过1毫秒。

如果C#编译为最终将转换为x86、x64或各种ARM(仅3种)体系结构的IL,则不会有一个单一的答案。如果性能至关重要,C#就不是(这部分)工作的正确工具。@Damien#u不信者的评论是正确的(在我看来应该是答案)。它将取决于目标体系结构。@Damien和mura,这是一个问题,体系结构是多少,它可能是多少。在这样一个简单的代码中,我们可能正以与熨斗相同的速度运行。您令人失望的结果更多地来自于由
i
保护的
vector\u out[i]
。学习正确使用C语言,这是(转换的)C代码。我非常感谢你的回答。我只是想澄清一下,像你一样,我只对内部循环进行计时。@ArturoHernandez在你的链接示例中,你调用了
Stopwatch.StartNew()
,它立即构造并启动计时器,随后的
\u timer.Start()
不会重置计时器。您可以检查此处的备注是否正确,但仅在100000次迭代中的第一次迭代中存在问题。一经纠正,我得到了同样的答案。我还需要运行你的代码。Tks!!!!因为你使用的是毫秒,所以你得到的是136兆次。就像我在Visual Studio中运行的一样。@ArturoHernandez,你是对的,我已经相应地进行了修改。
ms: 73
MFLOPS: 136.986301...