Низкая производительность копирования в OpenCL (enqueueWriteBuffer & enqueueReadBuffer) - PullRequest
0 голосов
/ 28 января 2019

Я получал очень низкую производительность при копировании памяти между GPU и CPU (в обе стороны) с помощью enqueueWriteBuffer и enqueueReadBuffer.Итак, я написал тест, чтобы убедиться, что проблема была в этих двух функциях, и у меня все еще очень низкая производительность.

Мои тесты выполняют несколько копий, включая копию 1 ГБ, и все же лучший результат составляет около 3 ГБ /s.Напротив, тест CUDA «bandwidthTest.exe» достигает около 12 ГБ / с с размером копии 30 МБ.Я провожу весь тест на ноутбуке с NVIDIA 1050 GTX и CUDA 10.0.

Есть идеи, почему производительность может быть такой низкой?

Это код, который я использую для тестирования,Я строю это с помощью Qt.Итак, есть некоторые зависимости (QTime, QDebug):

#include <QCoreApplication>
#include "CL/cl.hpp"
#include <vector>
#include <QDebug>
#include <QTime>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    std::vector<cl::Platform> platforms;
    cl::Platform::get(&platforms);

    std::vector<std::string> platformsNames;
    for (auto & platform : platforms) {
        platformsNames.push_back(platform.getInfo<CL_PLATFORM_NAME>());
    }


    std::vector<cl::Device> all_devices;
    platforms[0].getDevices(CL_DEVICE_TYPE_ALL, &all_devices);
    auto device = all_devices[0];
    qDebug() << "Platform used: " << platformsNames[0].c_str() << ". Device used: " << device.getInfo<CL_DEVICE_NAME>().c_str();
    qDebug() << "Max work group size: " << device.getInfo<CL_DEVICE_MAX_WORK_GROUP_SIZE>();
    qDebug() << "Max items size: " << device.getInfo<CL_DEVICE_MAX_WORK_ITEM_SIZES>();
    cl::Context context(device);
    cl::CommandQueue queue(context);
    // 1KB, 1MB, 10MB, 100MB, 1GB
    size_t sizes[] = {1024, 1024 * 1024, 10 * 1024 * 1024, 100 * 1024 * 1024, 1024 * 1024 * 1024};
    qDebug() << "Write Buffers";
    for (auto size : sizes) {
        cl::Buffer buffer(context, CL_MEM_READ_WRITE, size);
        std::vector<unsigned char> t(size);
        QTime timerFFT;
        timerFFT.start();
        auto iterations = 100.0f;
        for (auto i = 0; i < iterations; i++) {
            int err = queue.enqueueWriteBuffer(buffer, true, 0, size, t.data());
        }
        auto elapsed = timerFFT.elapsed() / 1000.0f;
        qDebug() << "GB/s: " << size / (1024.0f * 1024.0f * 1024.0f) / elapsed * iterations;
    }
    qDebug() << "Read Buffers";
    for (auto size : sizes) {
        cl::Buffer buffer(context, CL_MEM_READ_WRITE, size);
        std::vector<unsigned char> t(size);
        QTime timerFFT;
        timerFFT.start();
        auto iterations = 100.0f;
        for (auto i = 0; i < iterations; i++) {
            int err = queue.enqueueReadBuffer(buffer, true, 0, size, t.data());
        }
        auto elapsed = timerFFT.elapsed() / 1000.0f;
        qDebug() << "GB/s: " << size / (1024.0f * 1024.0f * 1024.0f) / elapsed * iterations;
    }
    return a.exec();
}
...