Я пытаюсь запустить несколько разных задач в нескольких потоках ЦП параллельно, используя CUDA в каждом потоке. Используя стартовый проект для CUDA Visual Studio 2022, проект работает без проблем без openMP. Кроме того, openMP работает правильно и работает в нескольких потоках.
Проблема возникает при попытке использовать оба потока одновременно. Некоторые потоки работают безупречно, в то время как другие возвращают ошибки cudaMalloc и/или cudaMemcpy, но лишь время от времени в случайных потоках. Из 24 потоков, которые я запускаю, некоторые из них будут работать правильно, а другие выдают ошибки. Каждый раз, когда я запускаю программу, каждый раз меняется, какие потоки работают правильно, а какие нет: от 3-4 потоков, работающих до 20 или около того потоков без ошибок.
Вот мой источник код
файл test.cpp:
Я пытаюсь запустить несколько разных задач в нескольких потоках ЦП параллельно, используя CUDA в каждом потоке. Используя стартовый проект для CUDA Visual Studio 2022, проект работает без проблем без openMP. Кроме того, openMP работает правильно и работает в нескольких потоках.
Проблема возникает при попытке использовать оба потока одновременно. Некоторые потоки работают безупречно, в то время как другие возвращают ошибки cudaMalloc и/или cudaMemcpy, но лишь время от времени в случайных потоках. Из 24 потоков, которые я запускаю, некоторые из них будут работать правильно, а другие выдают ошибки. Каждый раз, когда я запускаю программу, каждый раз меняется, какие потоки работают правильно, а какие нет: от 3-4 потоков, работающих до 20 или около того потоков без ошибок. Вот мой источник код файл test.cpp: [code]#include #include #include "heads.h" int main() { #pragma omp parallel { test(); printf("Hello World... from thread = %d\n", omp_get_thread_num()); } return 0; } [/code] Файл heads.h: [code]#pragma once int test(); [/code] Файл tester.cu: [code]#include "cuda_runtime.h" #include "device_launch_parameters.h" #include #include "heads.h"
cudaError_t addWithCuda(int* c, const int* a, const int* b, unsigned int size);
__global__ void addKernel(int* c, const int* a, const int* b) { int i = threadIdx.x; c[i] = a[i] * b[i]; }
int test() { const int arraySize = 5; const int a[arraySize] = { 1, 2, 3, 4, 5 }; const int b[arraySize] = { 10, 20, 30, 40, 50 }; int c[arraySize] = { 0 };
// Add vectors in parallel. cudaError_t cudaStatus = addWithCuda(c, a, b, arraySize); if (cudaStatus != cudaSuccess) { fprintf(stderr, "addWithCuda failed!\n"); return 1; }
// cudaDeviceReset must be called before exiting in order for profiling and // tracing tools such as Nsight and Visual Profiler to show complete traces. cudaStatus = cudaDeviceReset(); if (cudaStatus != cudaSuccess) { fprintf(stderr, "cudaDeviceReset failed!"); return 1; }
return 0; }
// Helper function for using CUDA to add vectors in parallel. cudaError_t addWithCuda(int* c, const int* a, const int* b, unsigned int size) { int* dev_a = 0; int* dev_b = 0; int* dev_c = 0; cudaError_t cudaStatus;
// Choose which GPU to run on, change this on a multi-GPU system. cudaStatus = cudaSetDevice(0); if (cudaStatus != cudaSuccess) { fprintf(stderr, "cudaSetDevice failed! Do you have a CUDA-capable GPU installed?"); goto Error; }
// Allocate GPU buffers for three vectors (two input, one output) . cudaStatus = cudaMalloc((void**)&dev_c, size * sizeof(int)); if (cudaStatus != cudaSuccess) { fprintf(stderr, "cudaMalloc failed!c\n"); goto Error; }
// Launch a kernel on the GPU with one thread for each element. addKernel > (dev_c, dev_a, dev_b);
// Check for any errors launching the kernel cudaStatus = cudaGetLastError(); if (cudaStatus != cudaSuccess) { fprintf(stderr, "addKernel launch failed: %s\n", cudaGetErrorString(cudaStatus)); goto Error; }
// cudaDeviceSynchronize waits for the kernel to finish, and returns // any errors encountered during the launch. cudaStatus = cudaDeviceSynchronize(); if (cudaStatus != cudaSuccess) { fprintf(stderr, "cudaDeviceSynchronize returned error code %d after launching addKernel!\n", cudaStatus); goto Error; }
// Copy output vector from GPU buffer to host memory. cudaStatus = cudaMemcpy(c, dev_c, size * sizeof(int), cudaMemcpyDeviceToHost); if (cudaStatus != cudaSuccess) { fprintf(stderr, "cudaMemcpy failed!c\n"); goto Error; }