Trying to get pointers working

841 views Asked by At

I've never needed to use pointers in C# before, however, the library I'm using requires that method parameters are passed as pointers. The library allows for the usage of SIMD instruction sets.

To test how to use the library, I've attempted to write a method which uses SIMD to calculate the cosine value of all the elements of an array in one go.

This is what I've got:

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;
}

However, I get these errors:

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*'

How do I get the pointers to work in this code? Again, this is the first time pointers has come up while I've been using C#.

2

There are 2 answers

1
Marat Dukhan On BEST ANSWER

The methods in Yeppp! library have two overloads: one that takes array + offset and another that takes pointers (e.g. if you want to call them with stackalloc'ed memory). E.g. for cosine computation Yeppp! offers two overloads:

Thus, your example should be rewritten as:

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;
}

Note that only one call per array is required (even if you used pointers).

1
MarcinJuraszek On

You have to use fixed statement to get pointer from array.

Probably something like that:

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;
}