CUDA编程:GPU并行与CPU并行的效率对比

#include <algorithm>
#include <chrono>
#include <cuda.h>
#include <cuda_runtime.h>
#include <functional>
#include <iostream>
#include <memory>
#include <random>
#include <thread>

namespace
{
constexpr int ADD_COUNT = 1 << 19;
}

__global__ void dev_add(int *a, int *b);

int main()
{
    cudaDeviceProp devProp;
    cudaGetDeviceProperties(&devProp, 0);
    const int BLOCK_PER_GRID = devProp.multiProcessorCount;
    const int THREAD_PER_BLOCK = devProp.maxThreadsPerBlock;
    const int TOTAL_COUNT = BLOCK_PER_GRID * THREAD_PER_BLOCK;
    const int BUFFER_SIZE = TOTAL_COUNT * sizeof(int) + 1024;

    auto a{std::make_unique<int[]>(TOTAL_COUNT)}, b{std::make_unique<int[]>(TOTAL_COUNT)},
        c{std::make_unique<int[]>(TOTAL_COUNT)};
    std::default_random_engine gen{
        unsigned(std::random_device{}() + std::chrono::steady_clock::now().time_since_epoch().count())};
    std::for_each(a.get(), a.get() + TOTAL_COUNT, [&gen](int &cur) { cur = gen() % 100; });
    std::for_each(b.get(), b.get() + TOTAL_COUNT, [&gen](int &cur) { cur = gen() % 100; });
    std::copy_n(b.get(), TOTAL_COUNT, c.get());

    std::cout << "Total: " << TOTAL_COUNT << '\n';

    std::cout << "GPU Start\n";
    {
        auto t0 = std::chrono::steady_clock::now();

        int *rd_a, *rd_b;
        cudaMalloc(&rd_a, BUFFER_SIZE);
        cudaMalloc(&rd_b, BUFFER_SIZE);
        std::unique_ptr<int[], std::function<void(int *)>> d_a{rd_a, cudaFree}, d_b{rd_b, cudaFree};

        cudaMemcpy(d_a.get(), a.get(), BUFFER_SIZE, cudaMemcpyHostToDevice);
        cudaMemcpy(d_b.get(), b.get(), BUFFER_SIZE, cudaMemcpyHostToDevice);
        dim3 blkd(BLOCK_PER_GRID), thrd(THREAD_PER_BLOCK);
        dev_add<<<blkd, thrd>>>(d_a.get(), d_b.get());
        cudaMemcpy(b.get(), d_b.get(), BUFFER_SIZE, cudaMemcpyDeviceToHost);

        auto t1 = std::chrono::steady_clock::now();
        std::cout << "GPU: " << std::chrono::duration_cast<std::chrono::milliseconds>(t1 - t0).count() << '\n';
    }

    std::cout << "\nCPU Start\n";
    {
        auto t0 = std::chrono::steady_clock::now();

        const int hc = std::thread::hardware_concurrency();
        const int per = (TOTAL_COUNT + hc - 1) / hc;
        auto ths{std::make_unique<std::thread[]>(hc)};
        for (int i = 0; i < hc; i++)
        {
            ths[i] = std::thread{[i, &per, &TOTAL_COUNT, &c, &a]() {
                for (int j = i * per, up = std::min((i + 1) * per, TOTAL_COUNT); j < up; ++j)
                {
                    int &cc = c[j], ca = a[j];
                    for (int k = 0; k < ADD_COUNT; k++)
                    {
                        cc = (cc + ca) % 100;
                    }
                }
            }};
        }
        for (int i = 0; i < hc; i++)
        {
            ths[i].join();
        }

        auto t1 = std::chrono::steady_clock::now();
        std::cout << "CPU: " << std::chrono::duration_cast<std::chrono::milliseconds>(t1 - t0).count() << '\n';
    }

    auto mis = std::mismatch(b.get(), b.get() + TOTAL_COUNT, c.get());
    if (mis.first != b.get() + TOTAL_COUNT)
        std::cout << "\nfirst mismatch postion: " << mis.first - b.get() << '\n';
    else
        std::cout << "\nmatched\n";

    return 0;
}

__global__ void dev_add(int *a, int *b)
{
    int idx = blockIdx.x * blockDim.x + threadIdx.x;
    int &cb = b[idx], &ca = a[idx];
    for (int i = 0; i < ADD_COUNT; ++i)
    {
        cb = (cb + ca) % 100;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
CUDA编程是一种用于GPU并行计算的编程模型,它由NVIDIA推出并应用于其显卡产品系列。通过CUDA编程,开发者可以利用GPU并行计算能力来加速各种计算任务。下面是一些关于CUDA编程GPU并行计算的重要概念: 1. GPU:图形处理器(Graphics Processing Unit)是一种专门用于处理图形和并行计算的硬件设备。与传统的中央处理器(CPU)相比,GPU具有更多的核心和更高的内存带宽,适合并行计算任务。 2. CUDA:Compute Unified Device Architecture(CUDA)是一种并行计算平台和编程模型,用于利用GPU进行通用目的的并行计算。CUDA提供了一套API和工具,使开发者能够直接在GPU上编写并运行并行计算代码。 3. 核函数(Kernel Function):在CUDA编程中,开发者可以定义一个称为核函数的特殊函数。核函数在GPU并行执行,并且每个线程都会独立地执行该函数。通过合理设计核函数,开发者可以利用GPU并行计算能力来加速各种计算任务。 4. 线程、块和网格:在CUDA编程中,GPU上的并行计算是以线程为基本单位进行的。线程被组织成块(block),而块又可以组织成网格(grid)。开发者可以通过调整块和网格的大小来优化并行计算的性能。 5. 内存管理:CUDA提供了多种类型的内存,开发者可以根据需要选择合适的内存类型。其中,全局内存(Global Memory)是GPU上所有线程都可以访问的共享内存,而共享内存(Shared Memory)是块内线程共享的高速缓存。合理地使用不同类型的内存可以提高并行计算的效率。 通过CUDA编程,开发者可以将适合并行计算的任务分配给GPU来加速处理。这种方式在科学计算、深度学习、图像处理等领域得到广泛应用,能够显著提高计算性能和效率

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值