加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – Mono SIMD性能恶化?

发布时间:2020-12-16 00:18:48 所属栏目:百科 来源:网络整理
导读:基准代码: using System;using System.Collections;using System.Collections.Generic;using System.Diagnostics;using System.Linq;using Mono.Simd;using MathNet.Numerics.LinearAlgebra.Single;namespace XXX {public static class TimeSpanExtensions
基准代码:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using Mono.Simd;
using MathNet.Numerics.LinearAlgebra.Single;

namespace XXX {
public static class TimeSpanExtensions {
    public static double TotalNanoseconds(this TimeSpan timeSpan) {
        return timeSpan.TotalMilliseconds * 1000000.0;
    }
}

public sealed class SimdBenchmark : Benchmark {
    Vector4f a = new Vector4f(1.0f,2.0f,3.0f,4.0f);
    Vector4f b = new Vector4f(1.0f,4.0f);
    Vector4f c;

    public override void Do() {
        c = a + b;
    }
}

public sealed class MathNetBenchmark : Benchmark {
    DenseVector a = new DenseVector(new float[]{1.0f,4.0f});
    DenseVector b = new DenseVector(new float[]{1.0f,4.0f});
    DenseVector c;

    public override void Do() {
        c = a + b;
    }
}

public sealed class DefaultBenchmark : Benchmark {
    Vector4 a = new Vector4(1.0f,4.0f);
    Vector4 b = new Vector4(1.0f,4.0f);
    Vector4 c;

    public override void Do() {
        c = a + b;
    }
}

public sealed class SimpleBenchmark : Benchmark {
    float a = 1.0f;
    float b = 2.0f;
    float c;

    public override void Do() {
        c = a + b;
    }
}

public sealed class DelegateBenchmark : Benchmark {
    private readonly Action _action;

    public DelegateBenchmark(Action action) {
        _action = action;
    }

    public override void Do() {
        _action();
    }
}

public abstract class Benchmark : IEnumerable<TimeSpan> {
    public IEnumerator<TimeSpan> GetEnumerator() {
        Do(); // Warm-up!

        GC.Collect(); // Collect garbage.
        GC.WaitForPendingFinalizers(); // Wait until finalizers finish.

        var stopwatch = new Stopwatch();

        while (true) {
            stopwatch.Reset();
            stopwatch.Start();
            Do();
            stopwatch.Stop();

            yield return stopwatch.Elapsed;
        }
    }

    IEnumerator IEnumerable.GetEnumerator() {
        return GetEnumerator();
    }

    public abstract void Do();
}

public struct Vector4 {
    float x;
    float y;
    float z;
    float w;

    public Vector4(float x,float y,float z,float w) {
        this.x = x;
        this.y = y;
        this.z = z;
        this.w = w;
    }

    public static Vector4 operator +(Vector4 v1,Vector4 v2) {
        return new Vector4(v1.x + v2.x,v1.y + v2.y,v1.z + v2.z,v1.w + v2.w);
    }
}

class MainClass {
    public static void Main(string[] args) {
        var avgNS1 = new SimdBenchmark().Take(1000).Average(timeSpan => timeSpan.TotalNanoseconds());
        var avgNS2 = new SimpleBenchmark().Take(1000).Average(timeSpan => timeSpan.TotalNanoseconds());
        var avgNS3 = new DefaultBenchmark().Take(1000).Average(timeSpan => timeSpan.TotalNanoseconds());
        var avgNS4 = new MathNetBenchmark().Take(1000).Average(timeSpan => timeSpan.TotalNanoseconds());


        Console.WriteLine(avgNS1 + " ns");
        Console.WriteLine(avgNS2 + " ns");
        Console.WriteLine(avgNS3 + " ns");
        Console.WriteLine(avgNS4 + " ns");
    }
}
}

环境设置:

Windows 7 / Mono 2.10.8 / MonoDevelop 2.8.5

MonoDevelop设置:

>工具>选项> .NET运行时>单声道2.10.8(默认)
>项目>选项>构建>一般>目标框架>单声道/ .NET
4
>项目>选项>构建>编译器>一般选项>启用优化
>项目>选项>构建>编译器>一般选项>平台目标> 86
>项目>选项>运行>一般>参数> -O = SIMD

结果:

> 94.4 ns
> 29.7 ns
> 49.9 ns
> 231595.2 ns

解决方法

我会先怀疑你的基准测试基础设施.

有几点可能是:

>您正在使用“秒表”计时单次操作 – 它没有分辨率>您的计时包括虚拟函数调用>您的样本量(1000)太小

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读