【问题标题】:Java vs. C++ - RaytracingJava 与 C++ - 光线追踪
【发布时间】:2011-11-18 21:29:59
【问题描述】:

作为一个业余项目,我在 Java 中创建了简单的光线追踪器,但是速度很慢。不是很慢,但仍然很慢。我想知道我是否可以使用 C 或 C++ 等低级语言获得任何性能提升,或者差异可以忽略不计,我应该坚持改进“我的”算法?

【问题讨论】:

    标签: java c++ performance raytracing


    【解决方案1】:

    由于您只知道实现背后的细节,因此很难回答。如果您的方法主要是数学方法,那么 Java 会在幕后进行各种优化,我认为您不会在切换到 C++ 后看到很多改进。

    如果您使用大量外部库,并且根据您在屏幕上显示光线追踪结果的方法,可能会在转向基于 C 的实现方面有所改进。

    【讨论】:

    • 我不使用任何外部库,显示结果实际上非常快。它产生了花费大部分时间的结果。如果有任何帮助,我可以包含 VisualVM 的屏幕...
    • C/C++ 中也有很多数学库。
    【解决方案2】:

    这将取决于。使用 C/C++ 将允许您访问在 Java 中无法完成的事情。 (如 SIMD)

    换句话说,我会说是的,通常可能在 C/C++ 中做得更好,但这需要一些工作。首先进行所有基本(数学/算法)优化。稍后再进行微优化。

    【讨论】:

    • “例如 SIMD” - 现代 JIT 已经对代码进行了矢量化处理,因此如果他不打算使用编译器内在函数,差异可能会非常小。
    • @Voo:这就是为什么我说“但这需要一些工作”。 SIMD 只是其中一个例子。
    • 它可能无法像人类那样做,因为它必须猜测要并行的内容。好吧,如果使用 SIMD,我可能会使用 OpenCL 而不是 CPU 指令。
    • 您不仅可以访问 C++ 中的 SIMD,还可以访问例如用Java写一个8字节节点的kd-tree实现?
    【解决方案3】:

    我的猜测是您会看到使用 c 或 c++ 显着提高性能。您可以尝试使用this 之类的工具转换您的代码。

    【讨论】:

    • 我看不出简单的代码翻译能带来多大的改进。
    • 因为使用优化编译 C 或 C++ 可能会产生比 HotSpot 更快的机器代码 - 但这是一个很大的可能。有很多因素可以提高或降低这两种语言的性能。
    【解决方案4】:

    几年前我用 Java 做了一个简单的光线追踪器。对于非常简单的网格(著名的茶壶 3D 网格和兔子 3D 网格),我可以通过实时渲染进行计算。所以我想你也可以做到 =)

    如果是爱好,坚持使用 Java,不值得转向 C++。而不是改变语言,想想你可以在哪里改进你的代码(找到在 log(n) 时间内被射线击中的三角形,多线程编程等......)

    【讨论】:

    • BSP?什么分辨率?有或没有抗锯齿?以及你使用什么硬件(所以我可以比较一下)。
    • 是的,BSP,必须有很好的分辨率,网格非常小(斯坦福兔子为 69,451 个三角形),没有抗锯齿,但我很确定我们做了一个简单的 phong 反射模型(茶壶看起来是圆形的,没有边缘)。计算机规格未知,但您可以猜到,那是三年前,在公共校园计算机上(可能是没有显卡的 E6200)
    【解决方案5】:

    如果您使用效率低下的算法,除了学习新语言的一大堆头痛之外,切换到 C/C++ 会给您带来边际收益。正确编写的 Java 可以实现类似 C/C++ 代码的大约 70-80% 的速度,并且对于非商业光线追踪器来说应该足够好。我假设光线追踪器现在功能完整,所以我的建议是学习如何使用分析器来检测代码中的瓶颈。记住 80/20 规则(或者是 90/10、75/25 左右?),您的程序将 80% 的时间花费在运行 20% 的代码上。

    更好的算法通常比语言切换提供更好的性能提升。

    【讨论】:

      【解决方案6】:

      我认为这个问题的答案是肯定的,在 99.99% 的情况下,非解释语言将比 VM 下的相同算法运行得更快。 这就是说(在内存和时间很重要的 java 和 c/c++ 中的图像处理方面做了很多工作)我认为你应该首先尝试优化你的代码,这是我的建议:

      • 尝试使用分析器找出代码的瓶颈。很多我们有时会忽略的东西都可以用这些工具来解决(比如类型转换、不必要的对象创建、最关键的功能,首先应该优化)分析器必须是你的朋友。

      然后(我可以看到几个光线追踪的例子):

      • 用查找表(只要可以)或approximate functions 替换 tan/sin/cos
      • 尝试按数组而不是按样本处理数据
      • 尝试使用多个线程

      现在这些东西“很好”,但如果速度对你来说真的很重要,我不建议使用 c 或 c++ 语言(即使你可以),但更有可能专注于 OpenCL。这可能是最好的工具,最适合构建光线追踪引擎。想象一下,您不是在谈论 30% 的改进,但更有可能是 10'000%(快 100 倍)这是一个 java 接口:http://jogamp.org/jocl/www/ 祝你好运:-)

      【讨论】:

      • 如果您通常可以注意到 JITed 代码和 c++ 编译器生成的代码之间的区别,您要么使用编译器内在函数来做编译器都无法完成的事情,请测量语言规范强制使用一种语言的情况变慢或测量错误。并且弄错后者是非常简单的(或者说:正确地做是非常困难的)。无论如何:使用 GPU 解决方案进行光线跟踪显然更胜一筹,在现代 CPU 上使用查找表可能不是一个好主意 ;-)
      • 嗯,我不明白最后一点:优化在大多数情况下(并非总是如此)是内存与 CPU 的权衡。查找表只是其中之一:这只是一种手动缓存(您肯定知道缓存对于使某些东西顺利运行的重要性;-))
      • 视情况而定。内存与 cpu 的权衡是众所周知的,但在这种情况下,重新计算 sin 可能比在表中查找要快 - 特别是如果您正在进行大量计算。该表还会从缓存中清除一些其他有用的数据,或者可能会自行清除(也不利于性能)。所以这是一个必须确定的基准。
      【解决方案7】:

      光线追踪的效率取决于您的加速结构。使用 C++ 而不是 Java 肯定会有所帮助。但是,如果您缺乏有效的结构,例如 BVH 或 Kd-tree,您的光线追踪器在您使用的任何语言中都会很慢。

      如果只是爱好,我建议留在 Java 上。如果你想加载复杂的模型,例如斯坦福佛或泰语,那么你绝对应该转向 C++ 并开始阅读“基于物理的渲染”:http://www.pbrt.org/你可以在http://pbrt.org/pbrt-2ed-chap4.pdf免费下载第 4 章

      简而言之,您可以根据项目目标回答您的问题。简单的爱好=留在 Java 上。复杂模型的实时 RT=C++

      【讨论】:

        【解决方案8】:

        AMD 刚刚发布了一个名为 Aparapi 的开源项目,它在运行时将 Java 字节码转换为 OpenCL。如果您的代码无法转换为 OpenCL(存在限制)或者您没有可用的 OpenCL,则代码将在线程池中运行。

        可能非常适合您的需求。

        http://aparapi.googlecode.com

        【讨论】:

        • 如果它运作良好,那就太令人印象深刻了,+1 表示有趣的发现在您发布的答案中提供有用的总结并补充链接
        猜你喜欢
        • 2015-09-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-12-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多