问题标签 [jocl]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
java - 如何创建 CL GL 互操作上下文?
对于 openGL,我使用 lwjgl,对于 openCL,我使用 jocl。
我的显卡rx550。
操作系统 win10pro。
这是我的 GL Init 方法,我先运行它。
这是我的 CL 初始化方法,我第二次运行它。
在这一部分中,他说 CL_INVALID_GL_SHAREGROUP_REFERENCE_KHR。
我尝试将 glfwGetCurrentContext() 更改为 wglGetCurrentContext() 和窗口,但他又说了一遍。
但是如果我删除这条线
他跑得很好,但如果我尝试把 texture3d
他说 CL_INVALID_CONTEXT。
java - 在 Java 中释放本地库分配的内存
如果您正在运行调用 Java 中的本机库的代码,那么当内存分配应该持续到对象的生命周期时,释放这些库分配的内存的常用方法是什么?在 C++ 中,我会使用析构函数,但 Java 从来没有真正拥有过这些,现在甚至更少了。
我最感兴趣的具体案例是JOCL,其中我有一个对象,该对象包装了已编译的 OpenCL 内核,并且其中的所有参数始终相同。表示已编译内核的结构和参数都在库端分配,JOCL 提供了一种方法clReleaseMemObject
,您可以调用该方法来减少指示何时应该删除对象的引用计数器(请注意,这与直接释放内存有点不同,但在这种情况下,我不这么认为)。
我假设如果程序终止时对象仍然存在,操作系统会清理所有内容,但我不太确定在线程中创建的对象。所以:
如果您希望在对象被垃圾回收时释放本机内存,是否有合适的地方调用释放此内存的方法?
如果对象是一个将持续一个线程持续时间的对象,是否有合适的地方进行此调用,或者这甚至是必要的吗?
java - OpenCL 和 Java - 奇怪的性能结果
我正在尝试使用 OpenCL 来提高一些使用JOCL的 Java 代码的性能。我一直在浏览他们网站上提供的示例,并使用它们组合了一个快速程序,以将其性能与正常运行的东西进行比较。不过,我得到的结果有点出乎意料,我担心我可能做错了什么。
首先,我使用的是 JOCL 0.1.9,因为我的 NVIDIA 卡不支持 OpenCL/JOCL 2.0。我的电脑有一个 Intel Core i7 CPU、一个 Intel HD Graphics 530 卡和一个 NVIDIA Quadro M2000M。
我编写的程序基于 JOCL 示例;它需要两个数字数组并将它们相乘,将结果放入第三个数组中。我使用 Java 的 nanoTime() 方法来粗略地跟踪 Java 观察到的执行时间。
程序的输出是:
这有两件事让我感到困惑:
- 为什么程序在使用 OpenCL 时在 CPU 上运行得这么快?它与 JVM 将使用的设备相同;我知道与 OpenCL 等低级语言相比,Java 速度较慢,但我认为它并没有那么慢。
- NVIDIA卡有什么问题?我知道考虑到他们的 CUDA 框架,他们对 OpenCL 的支持并不那么出色,但我仍然希望它至少比正常做事要快。事实上,备份,“这是在这里,以防万一你破坏你的真实图形卡”,英特尔 GPU 围绕它运行。
我担心我做错了什么,或者至少错过了一些能让它充分发挥潜力的东西。我能得到的任何指示都将非常受欢迎。
PS - 我知道因为我有一张 NVIDIA 卡,所以 CUDA 对我来说可能是更好/更快的选择;但是在这种情况下,我更喜欢 OpenCL 的灵活性。
更新:我能够找到我做错的一件事;依靠 Java 报告运行时是愚蠢的。我使用 OpenCL 的 profiling 东西编写了一个新测试,它得到了更合理的结果:
代码:
输出:
这似乎表明功能更强大的 NVIDIA 显卡实际上比 Intel 显卡性能更好,正如我所预料的那样。但...
- 为什么CPU仍然更快?
- 为什么普通的 Java 突然变得这么快?
java - 在 JOCL 中调用 clSetKernelArg 时出现 CL_INVALID_MEM_OBJECT 错误
编辑:意识到我在每次迭代时都在重新实例化 cl_context。现在可以了。
虽然这是一个 JOCL 特定的问题,但我相信它通常适用于 OpenCL。
我有一个程序将 int 数组发送到 OpenCL 内核以在 GPU 上进行处理,然后将结果返回给 Java。该程序在第一次迭代时运行良好,但是当第二次调用 clSetKernelArg(使用新数组)时,它会引发 CL_INVALID_MEM_OBJECT 错误。
我不明白为什么设置内核参数只会在第二次迭代时使程序崩溃。
这是Java代码的简化版本:
以下是 OpenCL 中相应内核的标头:
我让它工作的唯一方法是在每次迭代时重新实例化命令队列。但这是非常低效的。如何在不使程序崩溃的情况下再次调用 clSetKernelArg?
谢谢
opencl - 非常奇怪的 OpenCL CL_OUT_OF_RESOURCES 行为
我正在编写一个包含大量函数调用的相当大的 OpenCL 程序。我一直遇到 CL_OUT_OF_RESOURCES 错误的问题,但我设法用一个简单的 printf 语句解决了这个问题。这是有问题的代码片段:
这很好用,但是如果我删除 printf 函数,程序就会崩溃。如果我保留它,它不会。当它崩溃时,它会给出一个 CL_OUT_OF_RESOURCES 错误。谁能解释为什么添加 printf 会使程序不会耗尽资源?如果没有这个无用的 printf,我怎样才能完成这项工作?
相关规格:
- OpenCL 1.2
- 英伟达 GTX 660
- 使用 Java JOCL 作为宿主代码
编辑:
我注意到将 printf 语句放在其他地方会改变代码的运行方式。一些 printf 语句会导致程序输出不同的数字结果,而另一些会导致程序崩溃。
即使更改从未执行的代码也会极大地改变计算。就好像更改任何代码都会随机化它的执行方式。
这是显卡故障的征兆吗?或者可能是 OpenCL 编译器中的错误?
编辑 2
事实证明,递归不是问题。我删除了所有递归调用,但 printfs 和其他无害的更改仍然会根据代码的放置位置改变代码的运行方式。
这绝对是编译时的问题。
java - 如何使用 JOCL 将结构数组传递给内核
我正在使用 JOCL(Java 的 OpenCL 绑定)编写 OpenCL 光线追踪器。我想将一个结构数组传递给我的内核。该结构如下所示:
内核认为它是这样的:
做这个的最好方式是什么?最初,该结构没有该materialIndex
字段,所以我只是在 Java 中创建了一个浮点数组,用中心、半径和填充填充它,然后将其发送到内核。但是,当我添加时,materialIndex
我决定将我的程序转换为使用 NIO 缓冲区,这不起作用(数据已损坏)。
有没有更好的方法来使用 JOCL 将结构数组传递给内核?
java - 使用 JOCL/OpenCL 将图像复制到另一个
所以我的目标是将 GPU 用于我全新的 Java 项目,即创建游戏和游戏引擎本身(我认为这是深入了解其工作原理的好方法)。
我在 CPU 上使用 java.awt.Graphics2D 的多线程来显示我的游戏,但我在其他 PC 上观察到游戏运行速度低于 40FPS,所以我决定学习如何使用 GPU(我仍将渲染for 循环中的所有对象,然后在屏幕上绘制图像)。
出于这个原因,我开始按照 OpenCL 文档编写代码,并且 JOCL 采样了一个简单的小测试,即将纹理绘制到背景图像上(让我们假设每个实体都有一个纹理)。
在每次渲染调用中都会调用此方法,并将此实体的背景、纹理和位置作为参数。
下面的两个代码都已更新以适应 @ProjectPhysX 建议。
这是在内核上运行的程序源。
常量 sampler_t 采样器 = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP | CLK_FILTER_NEAREST;
如果没有调用 write_imageui,背景将被涂成黑色,否则为白色。目前,我有点难以理解为什么 C 函数中的 pixel = 0,但我认为熟悉 JOCL 的人会很快发现我在这段代码中的错误。今天,也许明天,我对这段代码感到非常困惑,但我觉得我永远不会发现自己的错误。出于这个原因,我请求您帮助查看我的代码。我觉得自己像个白痴,我当时想不通。
opencl - 在 JOCL - Java OpenCL - 我可以传递设备指针数组吗?
我想写一个内核来计算向量乘积的总和,所以像
即a
和b
是长度为 k 的设备指针数组。
如何在 OpenCL 和 JOCL 中传递这样的参数?
image - 高效地同步排队许多小型 OpenCL 内核
TLDR:我怎样才能运行许多小内核,一次一个,而没有显着的开销?
我正在开发一个充当虚拟绿屏的项目。它接收图像馈送,查找类似于颜色键的像素,并用替换颜色替换这些像素。我计划将生成的图像提要作为 Windows 中的虚拟网络摄像头输出。完整的源代码在 Github 上。目前,我正在使用 Java 中的 OpenCL 绑定 (JOCL) 来加速该过程。主应用程序是用 JavaFX 和 Kotlin 编写的,我很熟悉,但 OpenCL 内核是用 C 编写的,我是新手。
这是我为该程序创建的主要“API”。我尝试使 API 接口相对开放,以便将来可以直接添加 Cuda 支持。
这是一个使用 API 实例处理帧的示例“过滤器”。
这是InitialComparison
内核的一个示例,它查找并替换相似的像素。
它工作得很好!比在 CPU 上运行要快得多,即使使用 Java 的多线程ExecutorService
。除了比较之外,我还运行了两个额外的过滤器:NoiseReduction
,它删除了大部分不被其他绿屏像素包围的绿屏像素,以及FlowKey
,它填充了绿屏像素之间的间隙。
问题在于,与通过clEnqueueNDRangeKernel
. 这意味着运行所有内核的开销太大,导致帧延迟。每个过滤器必须一次运行一个,直到图像被完全处理。
我目前对 OpenCL 的理解是,在排队内核中,每个工作组都将排队,没有任何特定的顺序,也不能保证总并发。因为这些过滤器必须在整个图像中一次应用一个,所以我能想到的唯一选择是将许多小内核排队。
我尝试将所有内核聚合成一个大内核(下面的代码)。有两个问题:
- 工作组在不考虑总并发的情况下运行,这意味着一行像素可以完成所有过滤器,而另一行像素根本没有运行。
- 当我为聚合内核实现锁时,它会冻结,因为并非所有工作组都在同时运行。
话虽如此,聚合内核的运行速度比拆分内核快 1,000 倍(我实现了一个小的帧延迟计数器)。这向我表明,与手头的任务相比,排队内核的开销太大了。
我可以做些什么来优化这个程序?有没有办法有效地将许多小内核排队?有没有办法重组内核以同时运行?如果需要,还请让我知道如何提高我的问题的质量。
谢谢!