返回或参数中某种类型的性能故障(Java)

返回或参数中某种类型的性能故障(Java),java,multithreading,performance,Java,Multithreading,Performance,我正在运行一个复杂的多线程java游戏,除了这个函数外,它工作得非常好。调用此函数时,大约0.01%的时间会导致四分之一秒的线程挂接。通过一系列的调试行和时间测量,它完全取决于这个函数(以及其他三个几乎完全相同的函数) 此功能的用途是在体素引擎游戏中提供附近块的光照级别。它仅在更新世界的某一部分时运行,这可能与渲染同时发生 请注意: 此功能在其预期功能的100%时间内准确工作 此功能会导致约四分之一秒的挂接时间(0.01%) 变量不同步 在程序中,每次调用函数的次数不得超过一次 所有变量都是较

我正在运行一个复杂的多线程java游戏,除了这个函数外,它工作得非常好。调用此函数时,大约0.01%的时间会导致四分之一秒的线程挂接。通过一系列的调试行和时间测量,它完全取决于这个函数(以及其他三个几乎完全相同的函数)

此功能的用途是在体素引擎游戏中提供附近块的光照级别。它仅在更新世界的某一部分时运行,这可能与渲染同时发生

请注意:

  • 此功能在其预期功能的100%时间内准确工作
  • 此功能会导致约四分之一秒的挂接时间(0.01%)
  • 变量不同步
  • 在程序中,每次调用函数的次数不得超过一次
  • 所有变量都是较大的非同步类的有效字段
  • 所有变量都是整数
  • 数组
    light[][]
    是一个
    字节[][][]
  • 此方法每次调用的次数不会超过一次,因为它是由较大的方法在较宽的时间间隔上进行同步的
我很确定外部同步不是问题所在

此函数的哪些部分可能会导致线程同步、CPU过度使用或堆栈填充问题,如何提高性能以消除这些渲染故障

public byte nsleftlighting(int[] coords){
    if(coords[0]<0)return 16;
    difx=chunkedx-chunks[coords[0]].X;
    difz=chunkedz-chunks[coords[0]].Z;
    if(coords[1]==0){ 
        if(-difx<=-(chunklimit)){return 16;}

        else if (-difx==0) {
            if(-difz>=0){
                proz=0;
                specialz=-difz;
            }else{
                specialz=difz-1;
                proz=1;
            }
            if(chunks[chunkxyid[1][proz][0][specialz]].loaded){
                return chunks[chunkxyid[1][proz][0][specialz]].light[15][coords[2]][coords[3]];
            }
            else{return 16;}
        } else {
            if(-difz>=0){
                proz=0;
                specialz=-difz;
            }else{
                specialz=difz-1;
                proz=1;
            }
            if(-difx>0){
                prox=0;
                specialx=-difx-1;
            }else{
                specialx=difx;
                prox=1;
            }
            if(chunks[chunkxyid[prox][proz][specialx][specialz]].loaded){
                return chunks[chunkxyid[prox][proz][specialx][specialz]].light[15][coords[2]][coords[3]];
            } else {return 16;}
        }
    }
    if(coords[1]>0){
        return chunks[coords[0]].light[coords[1]-1][coords[2]][coords[3]];
    }
    return 16;
}
public字节nsleftlighting(int[]coords){
if(坐标[0]=0){
proz=0;
specialz=-difz;
}否则{
specialz=difz-1;
proz=1;
}
如果(-difx>0){
prox=0;
specialx=-difx-1;
}否则{
specialx=difx;
prox=1;
}
if(已加载块[chunkxyid[prox][proz][specialx][specialz]]{
返回chunk[chunkxyid[prox][proz][specialx][specialz]]。light[15][coords[2]][coords[3]];
}else{return 16;}
}
}
如果(坐标[1]>0){
返回块[coords[0]]。轻[coords[1]-1][coords[2]][coords[3]];
}
返回16;
}

我在这里没有看到任何会导致性能问题的东西——至少不会有那么大的差异。数组访问应该非常快——即使是四维数组。[[这方面做得很好。]]

四分之一秒的时间并不是很长,这让我怀疑探查器是否就问题的根源向您撒谎。它可能对多维数组或该方法的某些其他属性的响应很差,但这些属性并不是很明显——至少对我来说是这样

一种可能性,不管多么遥远,是你的程序被交换了,而这些阵列相当大。如果它们不经常被访问,当一些内存页被交换时,您是否有可能看到一些IO

您评论说您正在使用挂钟计时器来确定例程需要250毫秒。您确定CPU在该时间段内实际执行了该方法吗?这可能是一个线程争用问题,在程序的其他部分占用了CPU吗?当这个方法花费很长时间时,你能看到CPU峰值是否经常出现吗


您是否有可能看到GC堆锁,并且它比其他例程对数组访问的影响更大?你能看一下记忆图,看看是否有相关性吗?给程序更多堆是否会影响问题发生的时间或频率?如果您正在运行Java,这将是一个更大的问题我在这里没有看到任何会导致性能问题的东西——至少不会有那么大的差异。数组访问应该非常快——即使是四维数组。[[这方面做得很好。]]

四分之一秒的时间并不是很长,这让我怀疑探查器是否就问题的根源向您撒谎。它可能对多维数组或该方法的某些其他属性的响应很差,但这些属性并不是很明显——至少对我来说是这样

一种可能性,不管多么遥远,是你的程序被交换了,而这些阵列相当大。如果它们不经常被访问,当一些内存页被交换时,您是否有可能看到一些IO

您评论说您正在使用挂钟计时器来确定例程需要250毫秒。您确定CPU在该时间段内实际执行了该方法吗?这可能是一个线程争用问题,在程序的其他部分占用了CPU吗?当这个方法花费很长时间时,你能看到CPU峰值是否经常出现吗


您是否有可能看到GC堆锁,并且它比其他例程对数组访问的影响更大?你能看一下记忆图,看看是否有相关性吗?给程序更多堆是否会影响问题发生的时间或频率?如果在Java中运行Java多维数组不能保证在内存中连续排列,那么这将是一个更大的问题(我不确定是否专门保证一维数组是连续的,但实际上它们是连续的)。因此,根据您访问元素的方式,CPU缓存可能需要经常更新(与访问一维数组中的连续或邻近元素(速度相当快)相反,整个数组或至少其连续块可以立即加载到缓存中;此外,较新的JVM实现可以在一些简单但不复杂的情况下优化索引绑定检查(循环)这使得数组访问速度几乎与任何语言(C)中的速度一样快。具体发生的情况取决于JVM实现和内存管理器。请参阅以获取参考

所以,使用多维