检测英伟达GPU 为什么需要下载java_将Java与Nvidia GPU配合使用(CUDA)

本文探讨了在Java项目中利用英伟达GPU进行计算的需求,特别是面对CUDA不支持Java的情况。讨论了CUDA编程的艺术性,强调GPU计算适合数据并行和计算密集型任务,并提到了OpenCL作为替代方案。还列举了各种Java到OpenCL或CUDA的绑定库和转换工具,以帮助Java开发者利用GPU加速计算。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我正在做一个用Java完成的业务项目,需要巨大的计算能力来计算业务市场。简单的数学运算,但包含大量数据。

我们订购了一些cuda gpu进行尝试,并且由于cuda不支持Java,我想知道从哪里开始。我应该建立一个JNI接口吗?我应该使用JCUDA还是其他方法?

我没有这个领域的经验,我想如果有人可以指导我一些事情,以便我可以开始研究和学习。

最佳答案

首先,您应该意识到CUDA不会自动加快计算速度这一事实。一方面,由于GPU编程是一门艺术,正确地实现它可能非常非常具有挑战性。另一方面,因为GPU仅适合某些类型的计算。

这听起来可能令人困惑,因为您基本上可以在GPU上进行任何计算。关键当然是您是否会实现良好的加速。这里最重要的分类是问题是任务并行还是数据并行。粗略地说,第一个是指多个线程正在或多或少地独立执行各自任务的问题。第二个问题涉及许多线程都在做相同的事情-但是在数据的不同部分上的问题。

后者是GPU擅长的一种问题:它们具有许多内核,并且所有内核都执行相同的操作,但是在输入数据的不同部分上运行。

您提到您拥有“简单的数学但有大量数据”。尽管这听起来像是一个完美的数据并行问题,因此非常适合GPU,但仍需要考虑另一个方面:GPU的理论计算能力(FLOPS,每秒浮点运算)非常快。但是它们经常受内存带宽的限制。

这导致了另一种问题分类。即问题是受内存限制还是受计算限制。

第一个是针对每个数据元素执行的指令数量很少的问题。例如,考虑并行向量加法:您必须读取两个数据元素,然后执行一次加法,然后将总和写入结果向量。在GPU上执行此操作时不会看到加速,因为单次添加不会补偿读取/写入内存的工作量。

第二个术语“计算边界”是指指令数量比存储器读/写数量多的问题。例如,考虑矩阵乘法:当n是矩阵的大小时,指令数将为O(n ^ 3)。在这种情况下,可以预期GPU在某种矩阵大小下的性能将超过CPU。另一个示例可能是对“少量”数据元素执行许多复杂的三角计算(正弦/余弦等)时。

根据经验:您可以假设从“主” GPU内存中读取/写入一个数据元素的延迟大约为500条指令。

因此,GPU性能的另一个关键点是数据局部性:如果您必须读取或写入数据(在大多数情况下,您必须; ;-)),则应确保数据保持尽可能近的距离。可能的GPU核心。因此,GPU具有某些内存区域(称为“本地内存”或“共享内存”),通常只有几KB大小,但是对于将要包含在计算中的数据特别有效。

So to emphasize this again: GPU programming is an art, that is only remotely related to parallel programming on the CPU. Things like Threads in Java, with all the concurrency infrastructure like ThreadPoolExecutors, ForkJoinPools etc. might give the impression that you just have to split your work somehow and distribute it among several processors. On the GPU, you may encounter challenges on a much lower level: Occupancy, register pressure, shared memory pressure, memory coalescing ... just to name a few.

但是,当您要解决数据并行,计算受限的问题时,GPU是可行的方法。

一般说明:您特别要求CUDA。但我强烈建议您也看看OpenCL。它有几个优点。首先,它是独立于供应商的开放行业标准,并且由AMD,Apple,Intel和NVIDIA实施OpenCL。此外,Java世界中对OpenCL的支持更加广泛。我唯一希望使用CUDA的情况是,当您想使用CUDA运行时库时,例如CUFFT用于FFT或CUBLAS用于BLAS(矩阵/矢量运算)。尽管有为OpenCL提供类似库的方法,但是除非您为这些库创建自己的JNI绑定,否则不能直接从Java端使用它们。

您可能还会发现,在2012年10月,OpenJDK HotSpot组启动了“ Sumatra”项目:http://openjdk.java.net/projects/sumatra/。该项目的目标是在JIT的支持下直接在JVM中提供GPU支持。当前状态和最初结果可以在其邮件列表中找到,网址为http://mail.openjdk.java.net/mailman/listinfo/sumatra-dev

但是,不久前,我收集了一些与“ Java on the GPU”有关的资源。我将在这里以没有特定顺序的方式再次总结这些内容。

(免责声明:我是http://jcuda.org/和http://jocl.org/的作者)

(字节)代码转换和OpenCL代码生成:

https://github.com/aparapi/aparapi:由AMD创建并积极维护的开源库。在一个特殊的“内核”类中,可以重写应并行执行的特定方法。使用自己的字节码读取器在运行时加载此方法的字节码。该代码被翻译成OpenCL代码,然后使用OpenCL编译器进行编译。然后可以在OpenCL设备上执行结果,该设备可以是GPU或CPU。如果无法编译到OpenCL中(或没有OpenCL可用),则仍将使用线程池并行执行代码。

https://github.com/pcpratts/rootbeer1:一个开源库,用于将Java的某些部分转换为CUDA程序。它提供了专用接口,可以实现这些接口以指示某个类应在GPU上执行。与Aparapi相比,它尝试自动将“相关”数据(即对象图的完整相关部分!)序列化为适合GPU的表示形式。

https://code.google.com/archive/p/java-gpu/:用于将带批注的Java代码(有一定限制)转换为CUDA代码的库,然后将其编译为在GPU上执行代码的库。该图书馆是根据博士学位论文开发的,其中包含有关翻译过程的深刻背景信息。

https://github.com/ochafik/ScalaCL:OpenCL的Scala绑定。允许特殊的Scala集合与OpenCL并行处理。在集合的元素上调用的函数可以是常用的Scala函数(有一些限制),然后将其转换为OpenCL内核。

语言扩展

http://www.ateji.com/px/index.html:Java的语言扩展,它允许并行构造(例如,并行的循环,OpenMP样式),然后使用OpenCL在GPU上执行。不幸的是,这个非常有前途的项目不再维护。

http://www.habanero.rice.edu/Publications.html(JCUDA):可以将特殊的Java代码(称为JCUDA代码)转换为Java-和CUDA-C代码的库,然后可以在该库上编译和执行GPU。但是,该图书馆似乎未公开可用。

https://www2.informatik.uni-erlangen.de/CN/research/JavaOpenMP/index.html:适用于具有CUDA后端的OpenMP构造的Java语言扩展

Java OpenCL / CUDA绑定库

https://github.com/ochafik/JavaCL:OpenCL的Java绑定:基于自动生成的低级绑定的面向对象的OpenCL库

http://jogamp.org/jocl/www/:OpenCL的Java绑定:基于自动生成的低级绑定的面向对象的OpenCL库

http://www.lwjgl.org/:OpenCL的Java绑定:自动生成的低级绑定和面向对象的便利类

http://jocl.org/:OpenCL的Java绑定:原始Op​​enCL API的1:1映射的低级绑定

http://jcuda.org/:CUDA的Java绑定:低级绑定,它是原始CUDA API的1:1映射

http://sourceforge.net/projects/jopencl/:OpenCL的Java绑定。自2010年以来似乎不再维护

http://www.hoopoe-cloud.com/:CUDA的Java绑定。似乎不再维护

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值