【问题标题】:Trying to get pointers working试图让指针工作
【发布时间】:2014-03-02 18:35:01
【问题描述】:

我以前从不需要在 C# 中使用指针,但是,我使用的库要求方法参数作为指针传递。该库允许使用 SIMD 指令集。

为了测试如何使用该库,我尝试编写一种方法,该方法使用 SIMD 一次性计算数组中所有元素的余弦值。

这就是我所拥有的:

double[] ValuesToCalculate = new double[MAX_SIZE];
double[] CalculatedCosines = new double[MAX_SIZE];

long Result;
Result = CalculateCosineArray(ValuesToCalculate, CalculatedCosines);

public static long CalculateCosineArraySIMD(double[] array, double[] result)
{
     Stopwatch stopwatch = new Stopwatch();
     stopwatch.Start();
     for (int i = 0; i < array.Length; i++)
     {
         Yeppp.Math.Cos_V64f_V64f(*array, result, MAX_SIZE);
     }

     stopwatch.Stop();
     return stopwatch.ElapsedMilliseconds;
}

但是,我收到以下错误:

The best overloaded method match for 'Yeppp.Math.Cos_V64f_V64f(double*, double*, int)' has some invalid arguments
Argument 1: cannot convert from 'double[]' to 'double*'
The * or -> operator must be applied to a pointer
Argument 2: cannot convert from 'double[]' to 'double*'

如何让指针在这段代码中工作?同样,这是我在使用 C# 时第一次出现指针。

【问题讨论】:

  • 您的方法似乎将双指针作为第二个参数,但您传递的是双数组。

标签: c# pointers simd yeppp


【解决方案1】:

您必须使用fixed 语句从数组中获取指针。

大概是这样的:

public static long CalculateCosineArraySIMD(double[] array, double[] result)
{
    Stopwatch stopwatch = new Stopwatch();
    stopwatch.Start();

    fixed (double* arrayPtr = array, resultPtr = result)
    {
        Yeppp.Math.Cos_V64f_V64f(arrayPtr, resultPtr, MAX_SIZE);
    };

    stopwatch.Stop();
    return stopwatch.ElapsedMilliseconds;
}

【讨论】:

  • 呸..对我来说太快了:P
【解决方案2】:

Yeppp 中的方法!库有两个重载:一个采用数组 + 偏移量,另一个采用指针(例如,如果您想使用 stackalloc'ed 内存调用它们)。例如。用于余弦计算 Yeppp!提供两个重载:

因此,您的示例应重写为:

double[] ValuesToCalculate = new double[MAX_SIZE];
double[] CalculatedCosines = new double[MAX_SIZE];

long Result;
Result = CalculateCosineArray(ValuesToCalculate, CalculatedCosines);

public static long CalculateCosineArraySIMD(double[] array, double[] result)
{
    Stopwatch stopwatch = new Stopwatch();
    stopwatch.Start();

    Yeppp.Math.Cos_V64f_V64f(array, 0, result, 0, MAX_SIZE);

    stopwatch.Stop();
    return stopwatch.ElapsedMilliseconds;
}

请注意,每个数组只需要一次调用(即使您使用了指针)。

【讨论】:

  • 我应该补充一点,@MarcinJuraszek 的答案是完全正确的,这就是数组版本在内部实现的方式
猜你喜欢
  • 2015-02-11
  • 2019-02-01
  • 2011-04-13
  • 2015-09-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-02
相关资源
最近更新 更多