如何使用嵌套循环将这个函数对等化?

时间:2019-06-01 12:52:47

标签: c++ visual-studio parallel-processing cuda nvidia

因此,我正在从此类中进行作业,我们必须使用给定的算法制作cuda版本,而根据我的实际知识将无法正常工作。

我尝试这样做,但是结果Buffer充满了相同的数字。我认为问题在于如何获取每个点的索引,因为我不完全了解网格/块/线程ID和组织的工作方式。

给出的功能

int SimulacionTornoCPU(int pasossim, int vtotal, int utotal)
{
    /* Parametros de mecanizado */
    double incA = 360.0 / (double)PuntosVueltaHelicoide;
    for (int u = 0; u < S.UPoints; u++) /* Para cada punto de la superficie */
    {
        for (int v = 0; v < S.VPoints; v++)
        {
            double AvanceMin = 1e10;
            double angle = 0.0;
            for (int i = 0; i < pasossim; i++)  /* Giro del torno en el eje X */
            {
                // Se rota el punto actual (solo interesa la coordenada y)
                double py = S.Buffer[v][u].y * cos(angle*M_PI_180) - S.Buffer[v][u].z * sin(angle*M_PI_180);
                // Calcula la distancia al origen del punto transformado 
                // Si y es la menor se almacena
                if (py < AvanceMin)
                {
                    AvanceMin = py;
                }
                angle += incA;
            }
            int p = S.VPoints*u + v;
            CPUBufferMenorY[p] = AvanceMin;
        }
    }
    return OKSIM;
}

我试图解决的问题:

__global__ 
void calculo(double* GPUBufferMenorY, TSurf S, double* incremento, int* pasossim){
    const int i = blockIdx.x * blockDim.x + threadIdx.x;
    const int j = blockIdx.y * blockDim.y + threadIdx.y;

    //printf(" ( %f , %f )\n", S.Buffer[i][j].y, S.Buffer[i][j].z);
    if (i < S.UPoints && j < S.VPoints){
        double angulo = 0.00;
        double avance = 1<<20;

        for (size_t w = 0; w < *pasossim; w++)  /* Giro del torno en el eje X */
        {

            // Se rota el punto actual (solo interesa la coordenada y)
            double py = S.Buffer[i][j].y * cos(angulo*M_PI_180) - S.Buffer[i][j].z * sin(angulo*M_PI_180);
            // Calcula la distancia al origen del punto transformado 
            // Si y es la menor se almacena
            if (py < avance)
            {
                avance = py;
            }
            angulo += *incremento;
        }

        GPUBufferMenorY[i*(S.VPoints)+j] = avance;
    }
}

int SimulacionTornoGPU(int *pasossim, int *vtotal, int *utotal){

    double *incA;
    double aux = 360.0 / (double)PuntosVueltaHelicoide;
    double* device_GPU;
    incA = &aux;

    cudaMallocManaged(&pasossim, sizeof(int));
    cudaMallocManaged(&incA, sizeof(double));


    cudaMalloc(&device_GPU, S.VPoints*S.UPoints * sizeof(double));

    cudaMemcpy(device_GPU,GPUBufferMenorY, S.VPoints*S.UPoints * sizeof(double), cudaMemcpyHostToDevice);

    int blockSize = 256;
    int numBlocks = (S.VPoints*S.UPoints + blockSize - 1) / blockSize;
    calculo<<<numBlocks, blockSize>>>(device_GPU,S,incA,pasossim);

    cudaDeviceSynchronize();

    cudaMemcpy( GPUBufferMenorY, device_GPU, S.VPoints*S.UPoints * sizeof(double), cudaMemcpyDeviceToHost);

    cudaFree(pasossim);
    cudaFree(incA);
    cudaFree(vtotal);
    cudaFree(utotal);
    cudaFree(device_GPU);

    return OKSIM;
}

这是使用的结构和变量(由老师完成):

struct sTPoint3D
    {
        double x;
        double y;
        double z;
    };
    typedef struct sTPoint3D TPoint3D;

    typedef struct sTConf TConf;

    struct sTSurf
    {
        int UPoints;
        int VPoints;
        TPoint3D** Buffer;
    };
    typedef struct sTSurf TSurf;

//GLOBAL VARIABLES
    TSurf S;
    double* GPUBufferMenorY;
    double* CPUBufferMenorY;
    double PasoHelicoide;
    int PuntosVueltaHelicoide;

输出应该在-10到0之间,但应该是-6.2somethingx e22或1百万

0 个答案:

没有答案