我之前从未需要在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#时第一次出现指针。
答案 0 :(得分:5)
您必须使用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;
}
答案 1 :(得分:4)
Yeppp中的方法!库有两个重载:一个采用数组+偏移,另一个采用指针(例如,如果你想用stackalloc'ed内存调用它们)。例如。用于余弦计算Yeppp!提供两个重载:
Yeppp.Math.Cos_V64f_V64f(double[] xArray, int xOffset, double[] yArray, int yOffset, int length)
对数组参数进行操作Yeppp.Math.Cos_V64f_V64f(double* x, double* y, int length)
对指针参数进行操作因此,您的示例应该重写为:
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;
}
请注意,每个数组只需要调用一次(即使您使用了指针)。