У меня есть код C++, который вызывает код CUDA. Я использую GTX 680 GPU. В настоящее время он работает так:Запуск параллельных ядер CUDA, вызванных из функций оболочки C++
fn_1(); //calls CUDA code (indirectly)
fn_a(); //calls CUDA code (indirectly), must run AFTER fn_1
fn_2(); //calls CUDA code (indirectly), must run AFTER fn_1
fn_b(); //calls CUDA code (indirectly), must run AFTER fn_2
fn_3(); //calls CUDA code (indirectly), must run AFTER fn_2
fn_c(); //calls CUDA code (indirectly), must run AFTER fn_3
и каждая функция, как это:
void fn_*(){
call_cuda_fn_x(); //calls CUDA code
call_cuda_fn_y(); //calls CUDA code, must run AFTER call_cuda_fn_x
}
Некоторые из этих функций не в полной мере использовать свой GPU (GTX 680). Поэтому я хотел бы, чтобы fn_2() и fn_a() выполнялись одновременно, а затем вызываем fn_3() и fn_b(), как только fn_2() заканчивается. Затем синхронизируйте все после вызова fn_c().
fn_1();
fn_2(); also launch fn_a()
fn_3(); also launch fn_b()
fn_c();
synchronise() //ensure that fn_a() && fn_b() && fn_c() have finished.
Могу ли я это сделать? Если да, можете ли вы набросать, как?
(Обратите внимание, что, например, fn_b() имеет внутри него несколько функций C++, которые должны запускаться последовательно - по-видимому, это означает, что мне нужно использовать более одного потока cpu, чтобы одновременно вызвать fn_2() и fn_a() ? - то есть я не могу полагаться только называя все мои CUDA ядра и только синхронизироваться в самом конце)
редактировать: добавлять к этому вопросу, чтобы убедиться, что он достаточно ясно ..
C++ функция call_cuda_fn_x() имеет вид, например:
void call_cuda_fn_x(){
.... //some c++ working
convolve<<<n_blocks, n_threads, n_floats*sizeof(float)>>>
(mat1, mat2, ..);
CUDA_CHECK_RETURN(cudaThreadSynchronize()); //Wait for the GPU work to finish, BEFORE calling the next CUDA code.
mat_mul<<<n_blocks, n_threads, n_floats*sizeof(float)>>>
(mat1, mat2, ..);
CUDA_CHECK_RETURN(cudaThreadSynchronize()); //Wait for the GPU work to finish.
.... //some more c++ working
}
Обратите внимание на необходимость вызова функции cudaThreadSynchronize() в этой функции C++.
Читали [требования] (http://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#conurrent-kernel-execution) для одновременного выполнения ядра, или изучил [примерный пример кода ядра] (http://docs.nvidia.com/cuda/cuda-samples/index.html#concurrent-kernels)? –
Роберт - спасибо. Очень полезно. Так что GTX680 может запускать параллельные ядра - хорошо. И, как я понимаю, в случаях, когда мои функции C++ не зависят от результатов кода CUDA (т.е. нет «if (cuda_answer> 0.0) {...}»), я могу одновременно запускать несколько потоков, каждый из которых который последовательно запускает свой код, все вызываемые из одного потока cpu - тоже хорошие. Где код C++ зависит от результатов cuda, я все еще не уверен, что делать, но я сейчас на полпути :) Спасибо. – osbert
Если хост-код зависит от результатов cuda, то вам (предположительно) нужно скопировать результаты cuda с устройства на хост. Выпустите устройство для размещения 'cudaMemcpyAsync' для этих результатов * в тот же поток *, где было запущено ядро, генерирующее эти результаты. Затем выпустите 'cudaStreamSynchronize' для этого потока, прежде чем использовать эти данные в главном коде. Одновременное выполнение ядра может быть проще достигнуть/наблюдать за linux вместо Windows (WDDM) по целому ряду причин. –