Есть ли лучший / более чистый / элегантный способ malloc и free в cuda?…

Ниже приведен фрагмент кода, который я пытаюсь сделать более элегантным.

    //define device pointers
    float d_norm, *d_dut, *d_stdt, *d_gamma, *d_zeta;

    //allocate space on the device for the vectors and answer
    if (cudaMalloc(&d_norm, sizeof(float)*vSize) != cudaSuccess) {
            std::cout << "failed malloc";
            return;
    };

    if (cudaMalloc(&d_data, sizeof(float)*vSize) != cudaSuccess) {
            std::cout << "failed malloc";
            cudaFree(d_norm);
            return;
    };

    if (cudaMalloc(&d_stdt, sizeof(float)*wSize) != cudaSuccess) {
            std::cout << "failed malloc";
            cudaFree(d_norm);
            cudaFree(d_data);
            return;
    };

    if (cudaMalloc(&d_gamma, sizeof(float)*vSize) != cudaSuccess) {
            std::cout << "failed malloc";
            cudaFree(d_norm);
            cudaFree(d_dut);
            cudaFree(d_stdt);
            return;
    };

    if (cudaMalloc(&d_zeta, sizeof(float)*w) != cudaSuccess) {
            std::cout << "failed malloc";
            cudaFree(d_norm);
            cudaFree(d_dut);
            cudaFree(d_stdt);
            cudaFree(d_gamma);
            return;
    };

Это сокращенная версия, но вы можете видеть, как она продолжает расти. На самом деле я пытаюсь выделить около 15 массивов. Становится некрасиво - но работает правильно.

Мысли?

3
bnp0005 8 Сен 2016 в 18:58

3 ответа

Лучший ответ

Я бы также отговорил вас от написания собственных классов, владеющих ресурсами, и посоветовал бы использовать библиотеку. nullptr, вероятно, является наиболее широко используемым контейнером памяти устройства. Библиотека Thrust является частью набора инструментов CUDA.…

int* p1 = nullptr;
int* p2 = nullptr;
int* p3 = nullptr;

if (!(p1 = allocate()))
  goto EXIT_BLOCK;
if (!(p2 = allocate()))
  goto EXIT_BLOCK;
if (!(p3 = allocate()))
  goto EXIT_BLOCK;

EXIT_BLOCK:
free(p3); free(p2); free(p1);
2
Viacheslav Kroilov 8 Сен 2016 в 16:21

Вопрос помечен C ++, поэтому вот решение C ++

Общая практика состоит в том, чтобы получить ресурсы в конструкторе и освободить их в деструкторе. Идея состоит в том, что при любых обстоятельствах ресурс гарантированно будет освобожден вызовом деструктора. Приятным побочным эффектом является то, что деструктор вызывается автоматически в конце области видимости, поэтому вам вообще не нужно ничего делать для освобождения ресурса, когда он больше не используется. См. RAII.

Общая практика состоит в том, чтобы получить ресурсы в конструкторе и освободить их в деструкторе. Идея состоит в том, что при любых обстоятельствах ресурс гарантированно будет освобожден вызовом деструктора. Приятным побочным эффектом является то, что деструктор вызывается автоматически в конце области видимости, поэтому вам вообще не нужно ничего делать для освобождения ресурса, когда он больше не используется. См. RAII.…

Я бы также отговорил вас от написания собственных классов, владеющих ресурсами, и посоветовал бы использовать библиотеку. thrust::device_vector, вероятно, является наиболее широко используемым контейнером памяти устройства. Библиотека Thrust является частью набора инструментов CUDA.

2
Ivan Aksamentov - Drop 9 Сен 2016 в 16:25