Я думаю, вы, возможно, неправильно понимаете, как cuda делает свою вещь, а также как эффективно кодировать cuda. Вы должны, переходя от последовательного к параллельному, думать о своих проблемах, таких как массивная сетка. Кроме того, у @talonmies есть точка - сама куда не может делать файл ввода / вывода. У вас есть, если я правильно помню, как 1 iostream, доступный одновременно, и если он будет использоваться параллельно, тогда вы получите такие вещи, как процессор 86421 процессора GPU, выводящий его результат в исходное поле до процессора процессора 12 (который, я полагаю, , вы не хотите, чтобы это случилось). Параллельный IO - это, по сути, одно условие гонки.
Из того, что я помню, основным порядком является
Ниже приведен пример этого рабочего процесса. Буду честным, друг, я не знаю, о чем идет речь, но это не то, d распараллеливать ваш код.
//GPU-executed function to add 2 numbers
//PRECONDITION: 3 pointers to arrays, size of the arrays
//POSTCONDITION: c = a+b
//NOTE: m = size of M
// n = m*2
__global__ void vecAddKernel(int *M, const int m, const int n)
{
// *******this is the part where you'd put your if/else statements******* //
int i = threadIdx.y + blockIdx.y * blockDim.x;//row
int j = threadIdx.x + blockIdx.x * blockDim.x;//col
if ((i < m) && (j < m)) {
M[n*i+j] += M[n*i+m+j] + M[n*i+m*n+j] + M[n*i+m*n+m+j];
}
}
//=========================================================
//Function to allocate memory, setup block size and
// grid size, and call vecAddKernel on the array
//PRECONDITION: array pointer a and the row size of square
// matrix a
//POSTCONDITION: a's first quadrant now contains the sum
// of all its other quadrants into it
void vecAdd(int *a, int size)
{
int *aD_ptr;
int memsize = size*size*sizeof(int);
int halfSize = size/2;
// ******* give array to cuda ******* //
errorCheck(1, cudaMalloc((void **) &aD_ptr, memsize));
errorCheck(2, cudaMemcpy(aD_ptr, a, memsize, cudaMemcpyHostToDevice));
// ******* This is, like, how much of your matrix you have cuda execute
// at once - a 32x32 tile of numbers? a 64x64 tile of numbers?
// Fun fact: if you make TILE_WIDTH 1x1 it's the same as sequential ******* //
dim3 dimBlock(TILE_WIDTH, TILE_WIDTH, 1);
dim3 dimGrid(ceil(halfSize/(float)TILE_WIDTH),
ceil(halfSize/(float)TILE_WIDTH), 1);
// ******* call parallel function to edit your matrix ******* //
vecAddKernel<<< dimGrid, dimBlock >>>(aD_ptr, halfSize, size);
// ******* give newly-edited matrix back to program ****** //
errorCheck(3, cudaMemcpy(a, aD_ptr, memsize, cudaMemcpyDeviceToHost));
cudaFree(aD_ptr);
}
И, конечно, входные и выходные функции (все полностью последовательные, я боюсь ...):
//Function to put large matrix from file into 4 smaller
// quarter matrices
//PRECONDITION: 1 pointer to a matrix of size matrixSize
// size of matrix
// infile containing square matrix easily
// divisible by 2
//POSTCONDITION: Matrix is loaded up with large matrix from file
void loadMatrix(int* M, const int matrixSize, istream& infile)
{
for (int i = 0; i < matrixSize; i++) infile >> M[i];
}
//=========================================================
//Function to output 1 square matrix to an outfile
//PRECONDITION: outfile, size of each array, and pointer to
// pre-loaded array
//POSTCONDITION: matrix is output and formatted into outfile
void output(ostream& outfile, const int size, int* M)
{
int n = size*2;
outfile << size << "\n";
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
outfile << M[n*i+j] << ' ';
}
outfile << endl;
}
}
As вы можете видеть, что они буквально всего лишь несколько вложенных для петель. Я искренне надеюсь, что это поможет вам в правильном направлении - мы проверил количество времени, затраченное на создание 16000x16000 матриц с этим материалом, и это было как ЧАСЫ вычисления разницы во времени. Всего стоит его для пакетной работы. Не сдавайся!