2016-01-10 24 views
1

Могу ли я запускать приложения без MPI CUDA одновременно на графических процессорах NVIDIA Kepler с MPS? Я хотел бы сделать это, потому что мои приложения не могут полностью использовать GPU, поэтому я хочу, чтобы они совместно работали вместе. Есть ли какой-нибудь пример кода для этого?Как использовать многопроцессорную службу Nvidia (MPS) для запуска нескольких не-MPI-приложений CUDA?

ответ

10

Необходимые инструкции содержатся в documentation для службы MPS. Вы заметите, что эти инструкции на самом деле не зависят от MPI или вызывают их, поэтому на самом деле нет ничего особенного в MPI.

Вот пошаговое руководство/пример.

  1. Прочитайте раздел 2.3 вышеупомянутой документации для различных требований и ограничений. Для этого я рекомендую использовать CUDA 7, 7.5 или более поздней версии. Были некоторые различия в конфигурации с предыдущими версиями CUDA MPS, которые я не буду здесь описывать. Кроме того, я продемонстрирую использование только одного сервера/одного GPU. Машина, которую я использую для тестирования, представляет собой узел CentOS 6.2 с использованием графического процессора K40c (cc3.5/Kepler) с CUDA 7.0. В узле есть другие графические процессоры. В моем случае заказ перечисления CUDA помещает мой K40c на устройство 0, но порядок перечисления nvidia-smi, по-видимому, помещает его как id 2 в порядке. Все эти детали имеют значение в системе с несколькими графическими процессорами, что влияет на приведенные ниже сценарии.

  2. Я создам несколько вспомогательных скриптов bash, а также тестовое приложение. Для тестового приложения нам нужно что-то с ядром (ядрами), которое, очевидно, может работать одновременно с ядрами из других экземпляров приложения, и нам также хотелось бы что-то, что делает его очевидным, когда эти ядра (из отдельных приложений/процессов) выполняются одновременно или нет. Чтобы удовлетворить эти потребности в демонстрационных целях, давайте иметь приложение, в котором есть ядро, которое работает только в одном потоке на одном SM, и просто ждет некоторое время (мы будем использовать ~ 5 секунд), прежде чем выходить и печатать сообщение. Вот тест приложение, которое делает это:

    $ cat t1034.cu 
    #include <stdio.h> 
    #include <stdlib.h> 
    
    #define MAX_DELAY 30 
    
    #define cudaCheckErrors(msg) \ 
        do { \ 
        cudaError_t __err = cudaGetLastError(); \ 
        if (__err != cudaSuccess) { \ 
         fprintf(stderr, "Fatal error: %s (%s at %s:%d)\n", \ 
          msg, cudaGetErrorString(__err), \ 
          __FILE__, __LINE__); \ 
         fprintf(stderr, "*** FAILED - ABORTING\n"); \ 
         exit(1); \ 
        } \ 
        } while (0) 
    
    
    #include <time.h> 
    #include <sys/time.h> 
    #define USECPSEC 1000000ULL 
    
    unsigned long long dtime_usec(unsigned long long start){ 
    
        timeval tv; 
        gettimeofday(&tv, 0); 
        return ((tv.tv_sec*USECPSEC)+tv.tv_usec)-start; 
    } 
    
    #define APPRX_CLKS_PER_SEC 1000000000ULL 
    __global__ void delay_kernel(unsigned seconds){ 
    
        unsigned long long dt = clock64(); 
        while (clock64() < (dt + (seconds*APPRX_CLKS_PER_SEC))); 
    } 
    
    int main(int argc, char *argv[]){ 
    
        unsigned delay_t = 5; // seconds, approximately 
        unsigned delay_t_r; 
        if (argc > 1) delay_t_r = atoi(argv[1]); 
        if ((delay_t_r > 0) && (delay_t_r < MAX_DELAY)) delay_t = delay_t_r; 
        unsigned long long difft = dtime_usec(0); 
        delay_kernel<<<1,1>>>(delay_t); 
        cudaDeviceSynchronize(); 
        cudaCheckErrors("kernel fail"); 
        difft = dtime_usec(difft); 
        printf("kernel duration: %fs\n", difft/(float)USECPSEC); 
        return 0; 
    } 
    
    
    $ nvcc -arch=sm_35 -o t1034 t1034.cu 
    $ ./t1034 
    kernel duration: 6.528574s 
    $ 
    
  3. Мы будем использовать Баш скрипт для запуска сервера MPS:

    $ cat start_as_root.bash 
    #!/bin/bash 
    # the following must be performed with root privilege 
    export CUDA_VISIBLE_DEVICES="0" 
    nvidia-smi -i 2 -c EXCLUSIVE_PROCESS 
    nvidia-cuda-mps-control -d 
    $ 
    
  4. И Баш скрипт для запуска 2 копии нашего тестового приложения " одновременно ":

    $ cat mps_run 
    #!/bin/bash 
    ./t1034 & 
    ./t1034 
    $ 
    
  5. Мы могли бы также иметь Баш скрипт, чтобы выключить сервер, хотя это не требуется для этого руководства:

    $ cat stop_as_root.bash 
    #!/bin/bash 
    echo quit | nvidia-cuda-mps-control 
    nvidia-smi -i 2 -c DEFAULT 
    $ 
    
  6. Теперь, когда мы просто запустить наше тестовое приложение с помощью mps_run сценария выше, но фактически не позволяет серверу MPS, мы получаем ожидаемое поведение, один экземпляр приложения берет ожидаемый ~ 5 секунд, в то время как другой экземпляр занимает примерно вдвое больше (~ 10 секунд), поскольку, поскольку он не запускается одновременно с приложением из другого процесса, он ждет 5 секунд, пока работает другое приложение/ядро, а затем тратит 5 секунд на свое собственное ядро, в общей сложности ~ 10 секунд:

    $ ./mps_run 
    kernel duration: 6.409399s 
    kernel duration: 12.078304s 
    $ 
    
  7. с другой стороны, если мы начнем сервер MPS первый, и повторите тест:

    $ su 
    Password: 
    # ./start_as_root.bash 
    Set compute mode to EXCLUSIVE_PROCESS for GPU 0000:82:00.0. 
    All done. 
    # exit 
    exit 
    $ ./mps_run 
    kernel duration: 6.167079s 
    kernel duration: 6.263062s 
    $ 
    

    мы видим, что оба приложения принимают одинаковое количество времени, чтобы бежать, потому что ядра работают одновременно, в связи с МПС.

  8. Вы можете экспериментировать по своему усмотрению. Если эта последовательность работает правильно для вас, но запуск собственного приложения, похоже, не дает ожидаемых результатов, одна из возможных причин может заключаться в том, что ваши приложения/ядра не могут одновременно работать с другими экземплярами приложения/ядер, к построению ваших ядер, а не к MPS. Вы можете проверить the requirements for concurrent kernels и/или изучить concurrentKernels sample app.

  9. Значительная часть информации здесь была переработана из теста/работы here, хотя презентация здесь с отдельными приложениями отличается от представленного там случая MPI.

 Смежные вопросы

  • Нет связанных вопросов^_^