2014-02-06 3 views
2

이전에 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#을 사용하면서 처음으로 포인터가 나타납니다.

+1

두 번째 매개 변수로 double 포인터를 사용하지만 double 배열을 전달하는 것으로 보입니다. –

답변

4

방법! 라이브러리에는 두 개의 오버로드가 있습니다. 하나는 배열 + 오프셋을 사용하고 다른 하나는 포인터를 사용합니다 (예 : stackalloc의 메모리로 호출하려는 경우). 예 : 코사인 계산을위한 Yeppp! 이 오버로드를 제공합니다 :

따라서 포인터 인수를 운영하고 배열 인수

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

    참고 만 포인터를 사용하는 경우에도 배열 당 하나의 호출이 필요합니다.

  • +0

    훌륭한 작품! 감사합니다 – user9993

    +0

    나는 @MarcinJuraszek 대답이 완벽하게 정확하다는 것을 덧붙여 야합니다. 이것은 어레이 버전이 내부적으로 구현 된 방법입니다 –

    5

    배열에서 포인터를 가져 오려면 fixed 문을 사용해야합니다. 그런

    아마 뭔가 : Yeppp에서

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

    Bah .. 나에게 너무 빠르다 : P –