Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trying to get pointers working

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#.

like image 472
user9993 Avatar asked Feb 09 '26 18:02

user9993


2 Answers

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;
}
like image 116
MarcinJuraszek Avatar answered Feb 13 '26 15:02

MarcinJuraszek


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:

  • Yeppp.Math.Cos_V64f_V64f(double[] xArray, int xOffset, double[] yArray, int yOffset, int length) which operates on array arguments
  • Yeppp.Math.Cos_V64f_V64f(double* x, double* y, int length) which operates on pointer arguments

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).

like image 44
Marat Dukhan Avatar answered Feb 13 '26 15:02

Marat Dukhan



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!