小编hus*_*sik的帖子

jMonkey优化类似于Java3D的

编辑:为了进行实时绘图,在opengl和opencl之间的"互操作性"中开始使用ljjgl(jmonkeyengine和jocl的基础),现在可以实时计算和绘制100k粒子.也许mantle版本的jmonkey引擎可以解决这个drawcall开销问题.

几天来,我一直在学习Eclipse(java 64位)中的jMonkey引擎(版本:3.0)并尝试使用GeometryBatchFactory.optimize(rootNode);命令优化场景.

没有优化(具有改变球体位置的能力):

在此输入图像描述

好的,只有1-fps来自pci-express带宽+ jvm开销.

通过优化(无法改变球体位置):

在此输入图像描述

现在即使三角形数量增加也是29 fps.

Java3D有一种setCapability()方法,即使在优化的形式下也能够读/写场景对象.jMonkey引擎3.0必须能够满足这个主题,但我找不到它的任何痕迹(搜索过的教程和示例,失败了).

问题:如何在jMonkey 3.0中设置场景节点的read/write position/rotation/scale功能optimized?如果你不能回答第一个问题,你能告诉我为什么在使用优化命令时三角数会增加吗?我是否必须创建一种新方法来访问图形卡并自己更改变量(可能是jogl?)?

场景信息:16k粒子(16x16 res的球体)+ 1点光源(以及4096分辨率的阴影).

我确信我们可以通过pci-express轻松地在几毫秒内发送数千个浮点数.

  • 附加信息:我正在使用Aparapi内核来更新粒子位置,这需要10毫秒(16k*16k的交互来计算力).(在优化模式下不会改变任何东西:()aparapi可以访问那些优化数据吗?

对于batchNode.batch();优化的情况,这里再次使用减少的对象数1 fps:

在此输入图像描述

对象编号现在只有几百个,但fps仍然是1!

将球体位置发送到gpu并让它计算顶点位置可能比计算cpu上的顶点以及向gpu发送大量数据更好.

这里没有人帮忙吗?已经尝试过batchNode但没有帮助.

我不想改变3d api,因为jMonkey人已经重新发明了轮子,我对目前的情况很满意.只是试图挤出更多的性能(取消阴影给出100%的速度,但质量也很重要!).

这个java程序将成为一个小行星撞击场景模拟器(将有小行星大小,质量,速度,角度的选择)与带有LOD的行进立方体算法(将是数百万个粒子).

Marching-cubes算法会大大减少三角形数.如果你无法回答这个问题,那么任何行进立方体(或任何O(n)凸包)算法都将被接受!数据:作为源的x,y,z数组和作为目标的三角形条形阵列(等面网格点)

谢谢.

以下是有关流的一些示例(分辨率低得多):

1)通过引力折叠立方体形状的岩石组: 在此输入图像描述

2)排斥力开始显现: 在此输入图像描述

3)排斥力+引力使得组形成更平滑的形状: 在此输入图像描述

4)组形成一个球体(如预期的那样): 在此输入图像描述

5)然后,一个大的恒星身体接近: 在此输入图像描述

6)即将触摸: 在此输入图像描述

7)影响的时刻: 在此输入图像描述

借助Barnes-Hutt算法和截断电位,粒子数将增加10倍(可能超过100倍).

不是Marching-Cubes算法,包裹nbody的鬼布可以给出低分辨率的船体(比BH更容易但需要更多的计算)

鬼布会受到nbody(重力+排除)的影响,但是不会受到包裹它的布的影响.Nbody不会被渲染,但布料网格将以较低的triange数量渲染.

在此输入图像描述 在此输入图像描述

如果MC或以上工作,这将使程序渲染一个包裹布,大约200倍的粒子.

java opengl java-3d jmonkeyengine aparapi

34
推荐指数
1
解决办法
3090
查看次数

指针的使用是否取消了相关变量的"register"属性?

在C中,指针的使用是否取消了相关变量的"register"属性?

#include<stdio.h>
#include<stdlib.h>
int main()
{
    register int clk=0;    //maybe register maybe not
    int *adr=&clk;         //not a register now? i have its address
    *adr=1;  //if i use this 1000000 times, does it exist in L1 at least?
    printf("%d",clk);
    return 0;

}
Run Code Online (Sandbox Code Playgroud)

给编译器错误"不能获取寄存器变量的地址",但它不是寄存器%100.这只是一次机会.

这是最慢的循环吗?

#include<stdio.h>
#include<stdlib.h>
int main()
{
    int *p;
    int i=0;
    p=&i;
for(*p=0;(*p)<100;(*p)++)
{
    //do nothing
}
    printf("%d ",i);
    return 0;

}
Run Code Online (Sandbox Code Playgroud)

如果我几乎所有的变量都是指针式的,只有三个变量只有带有"register"关键字的原始类型,那么编译器是否会使这三个变量"真正注册"的机会更高?

好.问题解决了.我学会了一些装配,发现这取决于优化级别和变量的波动性.使用__asm {}可确保它在寄存器中计算.谢谢.

c optimization assembly

11
推荐指数
1
解决办法
488
查看次数

3D影子实施理念

假设您的眼睛位于物体A上的表面点P1并且存在目标物体B并且物体B后面存在点光源.

问题:如果我看到光源并说"我在阴影中",如果由于物体B我看不到光线,我是对的吗?然后我将对象A的那个点标记为"A上的B的阴影点之一".

在此输入图像描述

如果这是真的,那么我们可以在A的表面上建立一个"阴影几何"(黑色)对象,然后由于光,B,A等的运动实时地改变它吗?让我们说球体(A)有1000个顶点而其他球体(B)也有1000个顶点,那么这意味着1个百万的比较吗?(是阴影,O(N ^ 2)(时间)复杂性?).我不确定复杂性,因为改变P1(眼睛)也会改变B的观察点(P1和光源点之间).那么二阶阴影和更高的阴影(例如两次物体之间多次反射的光线)?

我现在使用的是java-3D,但它没有阴影功能,所以我想转移到其他兼容java的库.

谢谢.

编辑:我需要在移动相机时禁用"相机"来构建阴影.我怎样才能做到这一点?这会严重降低性能吗?

新思路: java3D具有内置的碰撞检测功能.我将创建从光到目标多边形顶点的线(不可见),然后检查来自另一个对象的碰撞.如果发生冲突,请添加该顶点corrd.到阴影列表,但这只适用于点光源:(.

任何为java3d提供真正的阴影库的人都会非常有帮助.

java3D中非常小的样本Geomlib阴影/光线跟踪可能是最好的 Ray跟踪示例吗?

我知道这有点难,但至少有一百人可以试过.

谢谢.

java 3d java-3d shadow

11
推荐指数
1
解决办法
1786
查看次数

Java中的代码注入/汇编内联?

我知道Java是一种安全的语言,但是当需要矩阵计算时,我可以更快地尝试一下吗?

我在C++,Digital-Mars编译器和FASM中学习__asm {}.我想在Java中做同样的事情.如何在函数中内联汇编代码?这甚至可能吗?

像这样的东西(使用AVX支持CPU将数组的所有元素钳制到没有分支的值的矢量化循环):

JavaAsmBlock(
   # get pointers into registers somehow
   # and tell Java which registers the asm clobbers somehow
     vbroadcastss  twenty_five(%rip), %ymm0
     xor   %edx,%edx
.Lloop:                            # do {
    vmovups   (%rsi, %rdx, 4), %ymm1
    vcmpltps   %ymm1, %ymm0, %ymm2
    vblendvps  %ymm2, %ymm0, %ymm1, %ymm1  # TODO: use vminps instead
    vmovups    %ymm1, (%rdi, %rdx, 4)
    # TODO: unroll the loop a bit, and maybe handle unaligned output specially if that's common
    add         $32, %rdx
    cmp         %rcx, %rdx
    jb     .Lloop                  # } …
Run Code Online (Sandbox Code Playgroud)

java assembly inline-assembly

10
推荐指数
2
解决办法
2万
查看次数

Java LongStream用于求和数组元素

因为许多整数在求和时会溢出,所以我需要一个很长的流来完成这项工作,但它不会接受int数组.如何在流式传输时转换每个元素而不是使用long数组?

// arr is an int[]
LongStream s = Arrays.stream( arr); // error
result = s.reduce(0, Long::sum); 
Run Code Online (Sandbox Code Playgroud)

编辑:似乎整数流使用其方法变为长整数流,如Tagir Valeev的答案.

LongStream asLongStream();

java java-8 java-stream

6
推荐指数
1
解决办法
777
查看次数

不完整类型的无效使用(对于指向原子整型变量的指针)

当我写这篇文章时,

std::atomic<int> * tmp = new std::atomic<int>();
Run Code Online (Sandbox Code Playgroud)

g++ 编译器返回一个错误说

invalid use of incomplete type "struct std::atomic<int>"
Run Code Online (Sandbox Code Playgroud)

为什么会出现这个错误?我怎样才能避免这个?我是否需要将原子变量包装在类中并使用其指针?

智能指针也会发生同样的情况。

std::shared_ptr<std::atomic<int>> tmp = std::make_shared<std::atomic<int>> ();
Run Code Online (Sandbox Code Playgroud)

c++ pointers incomplete-type stdatomic

6
推荐指数
1
解决办法
5459
查看次数

为什么 x86 不实现直接的核心到核心消息传递汇编/CPU 指令?

经过认真的发展,CPU 获得了许多核心,在多个小芯片、numa 系统等上获得了分布式核心块,但数据仍然不仅必须通过 L1 缓存(如果在同一核心 SMT 上),而且还必须通过一些原子/互斥同步未经硬件加速的原始过程。

我想知道为什么英特尔或 IBM 没有想出这样的东西:

movcor 1 MX 5 <---- sends 5 to Messaging register of core 1
pipe 1 1 1 <---- pushes data=1 to pipe=1 of core=1 and core1 needs to pop it
bcast 1 <--- broadcasts 1 to all cores' pipe-0 
Run Code Online (Sandbox Code Playgroud)

使其比其他方法快得多?GPU 支持块级快速同步点,例如barrier()__syncthreads()。GPU 还支持本地阵列的并行原子更新加速。

当 CPU 增加 256 个核心时,此功能是否不会为在核心到核心带宽(和/或延迟)上遇到瓶颈的各种算法提供严重的扩展?

x86 assembly intel message-passing cpu-architecture

6
推荐指数
1
解决办法
597
查看次数

Java applet:jocl operations stop java3d

运行Jocl(opencl包装器)内核会禁用java3d输出.当opencl完成时,java3d继续工作.

我怎样才能让Opencl(jocl)和opengl(java3d)一起工作?我需要一些告诉"它的opencl时间"的命令,当它完成时它告诉"它现在的opengl时间".

不知何故,当opencl工作时,java3D Jpanel会冻结并变灰.

我做了一些跟踪,发现java3D正在骚扰opencl(jocl),jmonkey引擎3.0并没有这样做.另一个尝试显示jmonkey做同样的事情.突然所有粒子位置都停止通过opencl更新,然后所有位置都变为0,0,0.

为每个设备使用唯一的上下文,程序,ID,....

误差如何:当星系渲染得很平滑时,突然所有粒子投射到我没有创建的平面上,然后在飞机投射到一条线上几秒后最终将该线投射到一个点上.所有这些必须是因为缓冲区x [] y [] z []开始为所有元素变为零.

编辑:较低的gpu工作频率使错误频率降低.这可能会比使用furmark更难推动GPU,因为在本地进行计算可以更快地工作吗?或者这是jocl/jmonkey/java3d之间的时间/访问优先级问题?所有其他程序,包括furmark,稳定在1225MHz(hd7870鹰)但这可能在1000MHz(AMD默认的hd7870)更稳定或看起来不稳定,因为缓冲区被垃圾收集故障破坏?

Aparapi(java的opencl包装器)从来都不是问题,在1200MHz下工作正常甚至还有"驱动程序停止运行并恢复"错误.催化剂13.3 beta.Jocl 1.5.1和累1.5.2.Catalyst 13.4 whql也是如此.

放System.gc(); 就在内核重复循环立即出现错误之前,必须有一个我错过的垃圾收集

使用一些跟踪:clCreateBuffer方法存在垃圾回收问题

编辑:解决了问题.当使用CL.CL_MEM_USE_HOST_PTR属性时,主线程中clCreateBuffer创建的缓冲区似乎是子线程的垃圾(要收集).CL.CL_MEM_COPY_HOST_PTR解决了问题,以换取%1-%2的性能损失

谢谢.

java applet java-3d opencl jocl

5
推荐指数
1
解决办法
354
查看次数

C++数组访问优化

我修改了一个开源项目(粉末玩具)并始终使用/ O2(最大化速度)选项进行编译,启用了SSE2代码生成并且只检查了这个:

void membwand(void * destv, void * srcv, size_t destsize, size_t srcsize)
{
    size_t i;
    unsigned char * dest = (unsigned char*)destv;
    unsigned char * src = (unsigned char*)srcv;
    for(i = 0; i < destsize; i++){
        dest[i] = dest[i] & src[i%srcsize];
    }
}
Run Code Online (Sandbox Code Playgroud)

在这里我替换了下面的行

membwand(gravy, gravmask, size_dst, size_src);

membwand(gravx, gravmask, size_dst, size_src);

    // gravy, gravx and gravmask are 1MB each
Run Code Online (Sandbox Code Playgroud)

membwand2(gravy,gravx, gravmask, size_dst, size_src);   
    // sizes are same, why not put all in a single function?
Run Code Online (Sandbox Code Playgroud)

实现方式如下:

void …
Run Code Online (Sandbox Code Playgroud)

c++ optimization

5
推荐指数
1
解决办法
241
查看次数

Java可以识别CPU的SIMD优势; 或者只有循环展开的优化效果

这部分代码来自我的矢量类的dotproduct方法.该方法对目标矢量数组(1000个矢量)进行内积计算.

当向量长度为​​奇数(262145)时,计算时间为4.37秒.当向量长度(N)为262144(8的倍数)时,计算时间为1.93秒.

     time1=System.nanotime();
     int count=0;
     for(int j=0;j<1000;i++)
     {

             b=vektors[i]; // selects next vector(b) to multiply as inner product.
                           // each vector has an array of float elements.

             if(((N/2)*2)!=N)
             {
                 for(int i=0;i<N;i++)
                 {
                     t1+=elements[i]*b.elements[i];
                 }
             }
             else if(((N/8)*8)==N)
             {
                 float []vek=new float[8];
                 for(int i=0;i<(N/8);i++)
                 {
                     vek[0]=elements[i]*b.elements[i];
                     vek[1]=elements[i+1]*b.elements[i+1];
                     vek[2]=elements[i+2]*b.elements[i+2];
                     vek[3]=elements[i+3]*b.elements[i+3];
                     vek[4]=elements[i+4]*b.elements[i+4];
                     vek[5]=elements[i+5]*b.elements[i+5];
                     vek[6]=elements[i+6]*b.elements[i+6];
                     vek[7]=elements[i+7]*b.elements[i+7];


                     t1+=vek[0]+vek[1]+vek[2]+vek[3]+vek[4]+vek[5]+vek[6]+vek[7];
                     //t1 is total sum of all dot products.
                 }
             }
     }
     time2=System.nanotime();
     time3=(time2-time1)/1000000000.0; //seconds
Run Code Online (Sandbox Code Playgroud)

问题:将时间从4.37s减少到1.93s(快2倍)是JIT明智地决定使用SIMD指令还是只是我的循环展开的正面效果?

如果JIT不能自动进行SIMD优化,那么在这个例子中,JIT也没有自动完成展开优化,这是真的吗?

对于1M迭代(向量)和向量大小为64,加速乘数变为3.5X(缓存优势?).

谢谢.

java optimization performance simd loop-unrolling

4
推荐指数
2
解决办法
7005
查看次数