C# Junior and Intermediate Actual Combat—3DFlipBird (4) Buffer Pool and Performance Analysis (UPR + Night God Simulator)

Buffer pool concept:

The key to the cache pool is to cache the two words. How to cache it, that is, save it somewhere. Every time an object needs to be created, first check if there is any in the cache pool. If there is, use it from the cache pool. create. Put it in the buffer pool when it is used up,

Production Method:

Every time we create an obstacle, we should first find whether there are any obstacles in the buffer pool, and if there are any, we should take them out directly from the buffer pool. And because we have many different obstacles, we use a dictionary to find out whether the corresponding buffer pool is Exist, create one if you don't have one, put it in if you have one.
Buffer pool dictionary

public Dictionary<string, PoolDate> poolDic = new Dictionary<string, PoolDate>();

Buffer pool class: we find a parent object and put all the things in the pool under the corresponding pool


public class PoolDate
{
    
    
    public GameObject fatherObj;//缓存对象的父节点
    public List<GameObject> poolList;//对象的容器

    public PoolDate(GameObject obj, GameObject poolObj)
    {
    
    
         //给缓存池创造一个父对象,并且将其作为总pool的子物体
        fatherObj = new GameObject(obj.name);
        fatherObj.transform.parent = poolObj.transform;

        poolList = new List<GameObject>() {
    
     };
        PushObj(obj);//创建池子时将第一个物体放进去
    }

    /// <summary>
    /// 存物体
    /// </summary>
    /// <param name="obj"></param>
    public void PushObj(GameObject obj)
    {
    
    
        obj.SetActive(false);//失活,隐藏
        //存起来
        poolList.Add(obj);
        //设置父对象
        obj.transform.parent = fatherObj.transform;
    }

    /// <summary>
    /// 取物体
    /// </summary>
    /// <param name="name"></param>
    /// <param name="transform"></param>
    /// <returns></returns>
    public GameObject GetObj()
    {
    
    
        GameObject obj = null;

        obj = poolList[0];
        poolList.RemoveAt(0);

        obj.SetActive(true);
        //激活显示
        obj.transform.parent = null;//断开父子关系
        return obj;
    }
}

Write a creative method to replace the previous Instantiate method

Insert picture description here

We pass in the name of the object, and pass in the object and position to be created (if there is no pool, create the object based on this)
. The name is to change the name of the object (an object must not be in the pool for the first time, and the name will contain clone , The purpose is to change the clone to facilitate storage and retrieval)

 public GameObject GetObj(string name,GameObject gameObject,Transform transform)
    {
    
     
        //有池子,有东西
        if (poolDic.ContainsKey(name) && poolDic[name].poolList.Count > 0)
        {
    
    
            return (poolDic[name].GetObj());
        }
        else
        {
    
    
            Debug.Log("物体的名字"+name);
            Debug.Log("物体/池子不存在");
            var reNameObj = GameObject.Instantiate(gameObject, transform);//
            Debug.Log("实例化的物体的名字" + reNameObj.name);
            reNameObj.name = name;
            return null;
        }
        
    }

After the object appears for a certain period of time, instead of destroying the object, we put it in the corresponding pool. Use Push method instead of Destroy method.
In the ObstacleBase script, create a Push method, pass the object's own name and
Insert picture description here
Insert picture description here
define its own storage method in PoolManager, determine whether there is an object in the pool and whether it is stored in the pool with the corresponding name, and hide the object. (Activate the object when taken out)

public void PushObj(string name, GameObject obj)
    {
    
    //里面有池子
        if (poolObj == null)
        {
    
    
            poolObj = new GameObject("pool");
        }
        obj.SetActive(false);//失活,隐藏
        obj.transform.parent = poolObj.transform;//设置父对象
        if (poolDic.ContainsKey(name))
        {
    
    
            poolDic[name].PushObj(obj);
        }else//里面没有,加入一个
        {
    
    
            poolDic.Add(name, new PoolDate(obj, poolObj));
        }
    }
    

effect:

Insert picture description here
Insert picture description here
You can see Hierarchy window appears Pool, which is a different obstacle corresponding pond, whenever an object regular time, it will enter the buffer pool, while the other side will take priority objects to create objects from the buffer pool, then when the object is not enough to create
the final Clear the buffer pool at the end of the game (clearing the HP) (otherwise you may have problems restarting the game), and you can also clear the buffer pool every time you start the game.

Insert picture description here

Insert picture description here

Performance Testing:

The performance test is performed below. Here, UPR + Night God simulator is used for evaluation
( currently UPR does not support testing directly in the editor mode, either packaged test or profiler )

Assessment method:
download upr windows, download upr package is loaded into the project inside
Insert picture description here
Insert picture description here
the project package
download Yagami simulator
Insert picture description here

URP add test

Open the simulator and open UPR windows at the same time, log in on the urp official website-my project-create project-new test
Insert picture description here

Tested here 4 times, two times of medium quality packaging, two times of highest quality packaging (increasing the rendering pressure of the simulator), of which the buffer pool is used 2 times and the buffer pool is not used 2 times

Copy the Session id of the established test to Windows, and then select ADB. At this point, the simulator should be open and the corresponding app installed. After clicking Start, the test will begin. After the test, click Stop to complete the test (the official website has a video tutorial)
Insert picture description here
Insert picture description here

Result analysis:

Standard mobile phone packaging (medium quality)

First look at the impact of the buffer pool on performance under standard mobile phone packaging (medium quality)Insert picture description here

Buffer pool

Insert picture description here
Insert picture description here

Insert picture description here

No buffer pool

Insert picture description here

Insert picture description here
Insert picture description here
It can be seen that the buffer pool does not have a high impact on performance, the number of GCs is actually higher (maybe the test time is not the same), the peak time of GC has become longer, and the number of frames basically changes little, but the buffer pool is used The CPU runs more smoothly and the number of frames is more stable.

Highest quality packaging

Let's see if the buffer pool is effective if the rendering pressure is relatively high:

Insert picture description here

Buffer pool

Insert picture description here
Memory usage
Insert picture description here
GC
Insert picture description here

No buffer pool

Insert picture description here
Memory usage
Insert picture description here
GC
Insert picture description here

It can be seen that under high rendering pressure, the number of frames is directly reduced by half, and the number of frames using the buffer pool is still slightly lower. The memory situation is that the memory using the buffer pool is indeed used more, and the peak GC time and The situation under normal picture quality is the same, it is higher than not using the buffer pool. Another thing that is the same as the normal picture quality is that the CPU running time with the buffer pool is longer (less glitches) than the CPU without the buffer pool, indicating that the number of frames is more stable.
However, the number of GCs that use the buffer pool is more than that that is not used. This is confusing and may require more test samples.
For this project, the optimization of image quality is the most important thing, but the optimization of cpu is not so important. The difference between the two image quality directly causes the frame number to drop by half. Therefore, if you want to optimize, you should go to the model surface number, texture size, etc. To proceed (particles, shaders, etc.), you should look at the relevant parameters, but this time the focus is on the impact of GC on performance, and other indicators will be discussed next time. (First experience of UPR)

Guess you like

Origin blog.csdn.net/euphorias/article/details/109241201