数值计算+GPU加速算法

典型的CUDA程序的执行流程如下:
分配host内存,并进行数据初始化;
分配device内存,并从host将数据拷贝到device上;
调用CUDA的核函数在device上完成指定的运算;
将device上的运算结果拷贝到host上;
释放device和host上分配的内存。

下面为kernel的线程层次结构,由于SM的基本执行单元是包含32个线程的线程束,所以block大小一般要设置为32的倍数。
在这里插入图片描述

1. 背景介绍

由于之前在研究基于pyspark+GPU的实时及离线研究时,GPU的性能(运行时间)并没有得到提升或提升不明显。基于这个原因,该研究只针对基于python写cuda程序的数值计算加速算法(不考虑使用spark的场景),进一步研究对GPU的性能研究及使用场景分析。(之前项目上对GPU研究方面过多,暂时只能推出一点内容)

2. 测试环境

2.1. 硬件

在这里插入图片描述

2.2. 软件

在这里插入图片描述

3. 测试过程

3.1 测试数据及测试逻辑

(1)测试数据为python程序中自动生成的numpy类型的数组a和b。
 每个数组长度为1亿。
 每个数组长度为10亿。
 每个数组长度为100亿。
(2)测试逻辑为数组间的数值运算。

3.2 测试代码

import pycuda.autoinit
import pycuda.driver as drv
import numpy as np
from timeit import default_timer as timer

from pycuda.compiler import SourceModule
mod = SourceModule("""
__global__ void func(float *a, float *b, size_t N)
{
  const int i = blockIdx.x * blockDim.x + threadIdx.x;
  if (i >= N)
  {
    return;
  }
  float temp_a = a[i];
  float temp_b = b[i];
  a[i] = (temp_a * 10 + 2 ) * ((temp_b + 2) * 10 - 5 ) * 5;
  // a[i] = a[i] + b[i];
}
""")

func = mod.get_function("func")

def test(N):
    # N = 1024 * 1024 * 90   # float: 4M = 1024 * 1024

    print("N = %d" % N)

    N = np.int32(N)

    a = np.random.randn(N).astype(np.float32)
    b = np.random.randn(N).astype(np.float32)
    # copy a to aa
    aa = np.empty_like(a)
    aa[:] = a
    # GPU run
    nTheads = 256
    nBlocks = int( ( N + nTheads - 1 ) / nTheads )
    start = timer()
    func(
            drv.InOut(a), drv.In(b), N,
            block=( nTheads, 1, 1 ), grid=( nBlocks, 1 ) )
    run_time = timer() - start
    print("gpu run time %f seconds " % run_time)
    # cpu run
    start = timer()
    aa = (aa * 10 + 2 ) * ((b + 2) * 10 - 5 ) * 5
    run_time = timer() - start

    print("cpu run time %f seconds " % run_time)

    # check result
    r = a - aa
    #print( min(r), max(aa) )

def main():
  for n in range(1, 10):
    N = 1024 * 1024 * (n * 10)
    print("------------%d---------------" % n)
    test(N)

if __name__ == '__main__':
main()

4. 算法测试

4.1. CPU 构建

4.1.1. 资源列表

在这里插入图片描述

4.1.2. 截图列表

在这里插入图片描述
传统硬件概览
在这里插入图片描述

4.2. GPU 构建

4.2.1. 资源列表

在这里插入图片描述

4.2.2. 截图列表

在这里插入图片描述
传统资源概览
在这里插入图片描述

GPU硬件概览
在这里插入图片描述

4.3. 构建测试总结

在这里插入图片描述
CPU情况下:
平均内存:1亿 < 5亿 < 10亿
平均CPU:1亿 = 5亿 = 10亿
峰值磁盘写速率:1亿 ≈ 5亿 ≈ 10亿
峰值磁盘读速率:1亿 = 5亿 = 10亿
时间:1亿 < 5亿 < 10亿

GPU情况下:
平均内存:1亿 = 5亿 = 10亿
平均CPU:1亿 ≈ 5亿 ≈ 10亿
峰值磁盘写速率:1亿 ≈ 5亿≈ 10亿
峰值磁盘读速率:1亿 = 5亿 = 10亿
峰值GPU:1亿 < 5亿 < 10亿
GPU显存:10亿 < 1亿 < 5亿
时间: 1亿 < 5亿 < 10亿
结论

  1. 无论是CPU或者GPU同等运行条件下,随着数据量(数据长度)的增加,对于CPU的资源消费基本上保持不变,但是对GPU的利用率一直在提高。
  2. GPU运行时间比CPU运行时间快4-5倍。
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
数值计算大作业通常涉及复杂的数学运算和算法实现。在Java中进行数值计算大作业时,通常需要先理清题意和要求,然后进行适当的算法设计和程序编写。 首先,需要定义和设计合适的数据结构来存储原始数据和计算结果。这可能涉及到数组、矩阵、向量等数据结构的设计和实现。然后,根据题目要求选择合适的数值计算算法,比如求解微分方程、插值、最优化等问题都需要选择不同的算法进行实现。 在编写Java代码时,需要熟练使用Java语言的数学计算库,比如Math类提供了丰富的数学函数和运算符,同时也可以使用第三方数值计算库,比如Apache Commons Math等。 为了提高代码的可读性和可维护性,可以采用面向对象的设计思想,将数值计算的各个模块进行封装,提高代码的复用性。 此外,为了保证数值计算结果的准确性和稳定性,需要进行充分的测试和调试。在设计测试案例时,应该覆盖不同的边界情况和特殊情况,以确保程序的正确性和鲁棒性。 最后,为了提高代码的性能,还可以考虑使用多线程并行计算或者GPU加速来加快数值计算的速度。 综上所述,数值计算大作业的Java做法需要结合数学知识和算法设计,充分利用Java语言的特性和数学计算库,同时注重代码质量和性能优化,以实现高效、稳定和准确的数值计算

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值