【问题标题】:Pointer to struct containing System.Numerics.Vector<double> in C#指向 C# 中包含 System.Numerics.Vector<double> 的结构的指针
【发布时间】:2016-08-28 09:02:14
【问题描述】:

由于 SIMD,我正在尝试使用 System.Numerics 库制作具有 4 个双打的向量。所以我做了这个结构:

public struct Vector4D
{
    System.Numerics.Vector<double> vecXY, vecZW;

    ...

}

在这个阶段,我将其编码为 128 位 SIMD 寄存器。 它工作正常,但是当我想要这样的东西时:

Vector4D* pntr = stackalloc Vector4D[8];

我明白了:

无法获取托管类型 ('Vector4D') 的地址、大小或声明指向托管类型的指针

知道如何将 stackalloc 与 System.Numerics.Vector 一起使用吗?使用 System.Numerics.Vector4(浮点精度),指针没有问题,但我需要双精度。

【问题讨论】:

标签: c# pointers simd stackalloc system.numerics


【解决方案1】:

我解决了:

public struct Vector4D
{
    public double X, Y, Z, W;

    private unsafe Vector<double> vectorXY
    {
        get
        {
            fixed (Vector4D* ptr = &this)
            {
                return SharpDX.Utilities.Read<Vector<double>>((IntPtr)ptr);
            }
        }
        set
        {
            fixed (Vector4D* ptr = &this)
            {
                SharpDX.Utilities.Write<Vector<double>>((IntPtr)ptr, ref value);
            }
        }
    }

    private unsafe Vector<double> vectorZW
    {
        get
        {
            fixed (Vector4D* ptr = &this)
            {
                return SharpDX.Utilities.Read<Vector<double>>((IntPtr)((double*)ptr) + 2);
            }
        }
        set
        {
            fixed (Vector4D* ptr = &this)
            {
                SharpDX.Utilities.Write<Vector<double>>((IntPtr)((double*)ptr) + 2, ref value);
            }
        }
    }
...
}

这为您提供了用于 SIMD 操作的向量,您还可以使用指向结构的指针。不幸的是,它比使用没有 SIMD 的静态数组慢了大约 50%。

【讨论】:

  • 您引用的速度损失来自unsafe 转换。通常,您需要在更大的 SIMD 工作中分摊该成本以实现收益。如果您能够切换到使用托管指针而不是(不安全的)本机指针(即,尤其是现在在 C# 7.2“ref locals”的帮助下),那么您将获得两全其美,并且可能会看到 SIMD 收益您是最初希望。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-08-28
  • 1970-01-01
  • 2013-10-10
  • 1970-01-01
  • 1970-01-01
  • 2021-07-14
  • 1970-01-01
相关资源
最近更新 更多