编辑:为了进行实时绘图,在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轻松地在几毫秒内发送数千个浮点数.
对于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倍的粒子.
在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 {}可确保它在寄存器中计算.谢谢.
假设您的眼睛位于物体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是一种安全的语言,但是当需要矩阵计算时,我可以更快地尝试一下吗?
我在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) 因为许多整数在求和时会溢出,所以我需要一个很长的流来完成这项工作,但它不会接受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();
当我写这篇文章时,
std::atomic<int> * tmp = new std::atomic<int>();
Run Code Online (Sandbox Code Playgroud)
g++ 编译器返回一个错误说
Run Code Online (Sandbox Code Playgroud)invalid use of incomplete type "struct std::atomic<int>"
为什么会出现这个错误?我怎样才能避免这个?我是否需要将原子变量包装在类中并使用其指针?
智能指针也会发生同样的情况。
std::shared_ptr<std::atomic<int>> tmp = std::make_shared<std::atomic<int>> ();
Run Code Online (Sandbox Code Playgroud) 经过认真的发展,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 个核心时,此功能是否不会为在核心到核心带宽(和/或延迟)上遇到瓶颈的各种算法提供严重的扩展?
运行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的性能损失
谢谢.
我修改了一个开源项目(粉末玩具)并始终使用/ 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) 这部分代码来自我的矢量类的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(缓存优势?).
谢谢.