- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在做一个用Java完成的业务项目,需要巨大的计算能力来计算业务市场。简单的数学运算,但包含大量数据。
我们订购了一些cuda gpu进行尝试,并且由于cuda不支持Java,我想知道从哪里开始。我应该建立一个JNI接口吗?我应该使用JCUDA还是其他方法?
我没有这方面的经验,我想如果有人可以指导我一些事情,以便我可以开始研究和学习。
最佳答案
首先,您应该意识到CUDA不会自动加快计算速度这一事实。一方面,由于GPU编程是一门艺术,正确实现它可能非常非常具有挑战性。另一方面,因为GPU仅适合某些类型的计算。
这听起来可能令人困惑,因为您基本上可以在GPU上进行任何计算。关键当然是您是否会实现良好的加速。这里最重要的分类是问题是任务并行还是数据并行。粗略地说,第一个是指多个线程正在或多或少地独立执行各自任务的问题。第二个问题涉及许多线程都在做相同的事情-但是在数据的不同部分上的问题。
后者就是GPU擅长的问题:GPU有很多内核,所有内核都做同样的事情,但是在输入数据的不同部分上运行。
您提到您拥有“简单的数学但有大量数据”。尽管这听起来像是一个完美的数据并行问题,因此很适合GPU,但还需要考虑另一个方面:GPU的理论计算能力(FLOPS,每秒浮点运算)非常快。但是它们经常受内存带宽的限制。
这导致了另一种问题分类。即问题是受内存限制还是受计算限制。
第一个是针对每个数据元素执行的指令数量很少的问题。例如,考虑并行向量加法:您必须读取两个数据元素,然后执行一次加法,然后将总和写入结果向量。在GPU上执行此操作时不会看到加速,因为单次添加不会补偿读取/写入内存的工作量。
第二个术语“计算边界”是指指令数量比存储器读/写数量多的问题。例如,考虑矩阵乘法:当n是矩阵的大小时,指令数将为O(n ^ 3)。在这种情况下,可以预期GPU在某种矩阵大小下的性能将超过CPU。另一个示例可能是在“少量”数据元素上执行许多复杂的三角计算(正弦/余弦等)时。
根据经验:您可以假设从“主” GPU内存中读取/写入一个数据元素的延迟大约为500条指令...。
因此,GPU性能的另一个关键点是数据局部性:如果您必须读取或写入数据(在大多数情况下,您必须; ;-)),则应确保数据保持尽可能近的距离。可能的GPU核心。因此,GPU具有某些内存区域(称为“本地内存”或“共享内存”),通常只有几KB大小,但是对于将要包含在计算中的数据特别有效。
因此,再次强调这一点:GPU编程是一门艺术,它仅与CPU上的并行编程密切相关。 Java中的诸如Threads之类的东西,以及诸如ThreadPoolExecutors
,ForkJoinPools
等所有并发基础结构,可能给人的印象是,您只需要以某种方式拆分工作并将其分配到多个处理器中即可。在GPU上,您可能会遇到更低的挑战:占用率,寄存器压力,共享内存压力,内存合并……仅举几例。
但是,当您要解决数据并行,计算受限的问题时,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/EN/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绑定:低级绑定,它们是原始OpenCL 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绑定。似乎不再维护
关于java - 在Nvidia GPU上使用Java(CUDA),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25691084/
我正在编写一个具有以下签名的 Java 方法。 void Logger(Method method, Object[] args); 如果一个方法(例如 ABC() )调用此方法 Logger,它应该
我是 Java 新手。 我的问题是我的 Java 程序找不到我试图用作的图像文件一个 JButton。 (目前这段代码什么也没做,因为我只是得到了想要的外观第一的)。这是我的主课 代码: packag
好的,今天我在接受采访,我已经编写 Java 代码多年了。采访中说“Java 垃圾收集是一个棘手的问题,我有几个 friend 一直在努力弄清楚。你在这方面做得怎么样?”。她是想骗我吗?还是我的一生都
我的 friend 给了我一个谜语让我解开。它是这样的: There are 100 people. Each one of them, in his turn, does the following
如果我将使用 Java 5 代码的应用程序编译成字节码,生成的 .class 文件是否能够在 Java 1.4 下运行? 如果后者可以工作并且我正在尝试在我的 Java 1.4 应用程序中使用 Jav
有关于why Java doesn't support unsigned types的问题以及一些关于处理无符号类型的问题。我做了一些搜索,似乎 Scala 也不支持无符号数据类型。限制是Java和S
我只是想知道在一个 java 版本中生成的字节码是否可以在其他 java 版本上运行 最佳答案 通常,字节码无需修改即可在 较新 版本的 Java 上运行。它不会在旧版本上运行,除非您使用特殊参数 (
我有一个关于在命令提示符下执行 java 程序的基本问题。 在某些机器上我们需要指定 -cp 。 (类路径)同时执行java程序 (test为java文件名与.class文件存在于同一目录下) jav
我已经阅读 StackOverflow 有一段时间了,现在我才鼓起勇气提出问题。我今年 20 岁,目前在我的家乡(罗马尼亚克卢日-纳波卡)就读 IT 大学。足以介绍:D。 基本上,我有一家提供簿记应用
我有 public JSONObject parseXML(String xml) { JSONObject jsonObject = XML.toJSONObject(xml); r
我已经在 Java 中实现了带有动态类型的简单解释语言。不幸的是我遇到了以下问题。测试时如下代码: def main() { def ks = Map[[1, 2]].keySet()
一直提示输入 1 到 10 的数字 - 结果应将 st、rd、th 和 nd 添加到数字中。编写一个程序,提示用户输入 1 到 10 之间的任意整数,然后以序数形式显示该整数并附加后缀。 public
我有这个 DownloadFile.java 并按预期下载该文件: import java.io.*; import java.net.URL; public class DownloadFile {
我想在 GUI 上添加延迟。我放置了 2 个 for 循环,然后重新绘制了一个标签,但这 2 个 for 循环一个接一个地执行,并且标签被重新绘制到最后一个。 我能做什么? for(int i=0;
我正在对对象 Student 的列表项进行一些测试,但是我更喜欢在 java 类对象中创建硬编码列表,然后从那里提取数据,而不是连接到数据库并在结果集中选择记录。然而,自从我这样做以来已经很长时间了,
我知道对象创建分为三个部分: 声明 实例化 初始化 classA{} classB extends classA{} classA obj = new classB(1,1); 实例化 它必须使用
我有兴趣使用 GPRS 构建车辆跟踪系统。但是,我有一些问题要问以前做过此操作的人: GPRS 是最好的技术吗?人们意识到任何问题吗? 我计划使用 Java/Java EE - 有更好的技术吗? 如果
我可以通过递归方法反转数组,例如:数组={1,2,3,4,5} 数组结果={5,4,3,2,1}但我的结果是相同的数组,我不知道为什么,请帮助我。 public class Recursion { p
有这样的标准方式吗? 包括 Java源代码-测试代码- Ant 或 Maven联合单元持续集成(可能是巡航控制)ClearCase 版本控制工具部署到应用服务器 最后我希望有一个自动构建和集成环境。
我什至不知道这是否可能,我非常怀疑它是否可能,但如果可以,您能告诉我怎么做吗?我只是想知道如何从打印机打印一些文本。 有什么想法吗? 最佳答案 这里有更简单的事情。 import javax.swin
我是一名优秀的程序员,十分优秀!