     cout << "Points2 " << points2.size() << endl;
 
     clock_t myTime = clock();    
-    int size1 = (int(points1.size() / TILE_WIDTH) + 1) * TILE_WIDTH;
-    int size2 = (int(points2.size() / TILE_WIDTH) + 1) * TILE_WIDTH;
+    int size1 = (int(points1.size() / (TILE_WIDTH * 2)) + 1) * (TILE_WIDTH * 2);
+    int size2 = (int(points2.size() / (TILE_WIDTH * 2)) + 1) * (TILE_WIDTH * 2);
     int size = max(size1, size2);
     size_t corrSize = size1 * size2 * sizeof(float);
     cout << "corrSize = " << (size1 * size2) << endl;

    /*float * hCorr = (float *)malloc(corrSize);
    cutilSafeCall(cudaMemcpy(hCorr, d_corr, corrSize, cudaMemcpyDeviceToHost));

    for (int i = 0; i < 16; i++) {
        cout << i << " ";
        for (int j = 0; j < 32; j++) {
            cout << j << "[" << hCorr[i * size2 + j] << "]";
        }
        cout << endl;
    }
    cout << endl;
    //free(hCorr);//*/

    timings.tCalcCorrelation = clock() - myTime;
    myTime = clock();

    //calcBestCorr <<< blocksPerGrid, threadsPerBlock >>> (d_corr, d_bestCorr1, d_bestCorr2, points1.size(), points2.size());
    dim3 dimBlockBestCorrX(BEST_CORR_Y, BEST_CORR_X);
    dim3 dimGridBestCorrX(size1 / BEST_CORR_Y, 1);
    bestCorrX <<< dimGridBestCorrX, dimBlockBestCorrX >>> (d_corr, d_bestCorr2, size1, size2);
    cudaThreadSynchronize();

    timings.tCalcBestCorr = clock() - myTime;
    myTime = clock();

    int * bestCorr2 = (int *)malloc(size1 * sizeof(int));
    cutilSafeCall(cudaMemcpy(bestCorr2, d_bestCorr2, size1 * sizeof(int), cudaMemcpyDeviceToHost));

    for (int i = 0; i < points2.size(); i++) {
        cout << "[" << bestCorr2[i] << "]";
    }
    cout << endl;    
    free(bestCorr2);//*/

    /*blocksPerGrid = ((points1.size() - 1) / threadsPerBlock) + 1;
    calcMatches <<< blocksPerGrid, threadsPerBlock >>> (d_bestCorr1, d_bestCorr2, d_matches, points1.size());
    cudaThreadSynchronize();


    }

    if (ty == 0) {
        bestCorr2[partialCorrPos] = partialIdx[ty][tx];
    }
}

__global__
void bestCorrY(float * corr, int * bestCorr1, int size1, int size2) {
    __shared__ float partialComp[BEST_CORR_Y][BEST_CORR_X];
    __shared__ int partialIdx[BEST_CORR_Y][BEST_CORR_X];

    unsigned int tx = threadIdx.x;
    unsigned int ty = threadIdx.y;
    unsigned int bx = blockIdx.x;
    unsigned int by = blockIdx.y;
    float tmpVal = 0;

    unsigned int yPos = (by * BEST_CORR_Y + ty) * size2;
    unsigned int xPos = 0;

    partialComp[ty][tx] = corr[yPos + tx];
    partialIdx[ty][tx] = tx;

    // Obtenemos el mayor de cada "pseudobloque"
    for (unsigned int i = BEST_CORR_X; i < size2; i += BEST_CORR_X) {
        xPos = i + tx;
        tmpVal = corr[yPos + xPos];
        if (partialComp[ty][tx] < tmpVal) {
            partialComp[ty][tx] = tmpVal;
            partialIdx[ty][tx] = xPos;
        }
    }

    // Obtenemos el mayor para el bloque inicial
    for (unsigned int stride = blockDim.x>>1; stride > 0; stride >>= 1) {
        __syncthreads();
        if (tx < stride) {
            if (partialComp[ty][tx + stride] > partialComp[ty][tx]) {
                partialComp[ty][tx] = partialComp[ty][tx + stride];
                partialIdx[ty][tx] = partialIdx[ty][tx + stride];
            }
        }
    }

    if (tx == 0) {
        bestCorr1[ty + by * BEST_CORR_Y] = partialIdx[ty][tx];
    }    
}

__global__
