Wednesday, April 29, 2020

deadly diamond of death


Unity Performance: CPU Slicing Secrets

https://thegamedev.guru/unity-performance/cpu-slicing-secrets/

One Single Update () function

public class SingletonAsComponent<T> : MonoBehaviour where T : 
SingletonAsComponent<T> {
  
  private static T __Instance;
  
  protected static SingletonAsComponent<T> _Instance {
      get {
        if(!__Instance) {
              T [] managers = 
              GameObject.FindObjectsOfType(typeof(T)) as T[];
              if (managers != null) {
                  if(managers.Length == 1) {
                      __Instance = managers[0];
                      return __Instance;
                  } else if (managers.Length > 1) {
                      Debug.LogError("You have more than one " + 
                      typeof(T).Name + " in the scene. You only 
                      need 1, it's a singleton!");
                      for(int i = 0; i < managers.Length; ++i) {
                          T manager = managers[i];
                          Destroy(manager.gameObject);
                      }
                  }
              }

              GameObject go = new GameObject(typeof(T).Name, 
              typeof(T));
              __Instance = go.GetComponent<T>();
              DontDestroyOnLoad(__Instance.gameObject);
          }
          return __Instance;
      } 
      set {
          __Instance = value as T;
      }
  }
}
public class MySingletonComponent : SingletonAsComponent<MySingletonComponent> {
  public static MySingletonComponent Instance {
    get { return ((MySingletonComponent)_Instance); }
    set { _Instance = value; }
  }
}
This class can be used at runtime by having any other object access the Instance property at any time. If the Component does not already exist in our Scene, then the SingletonAsComponent base class will instantiate its own GameObject and attach an instance of the derived class to it as a Component. From that point forward, access through the Instance property will reference the Component that was created.
Proper cleanup of a Singleton Component can be a little convoluted because of how Unity tears down Scenes. An object's OnDestroy() method is called whenever it is destroyed during runtime. The same method is called during application shutdown, whereby every Component on every GameObject has its OnDestroy() method called by Unity. Application shutdown also takes place when we end Play Mode in the Editor and return to Edit Mode. However, destruction of objects occurs in a random order, and we cannot assume that the Singleton Component will be the last object destroyed.
Consequently, if any object attempts to do anything with the Singleton in the middle of their OnDestroy() method, then they will be calling the Instance property. If the Singleton has already been destroyed prior to this moment, then calling Instance during another object's destruction would create a new instance of the Singleton Component in the middle of application shutdown! This can corrupt our Scene files, as instances of our Singleton Components will be left behind in the Scene. If this happens, then Unity will throw the following error message at us:
The reason some objects may wish to call into our Singleton during destruction is that Singletons often make use of the Observer pattern. This design pattern allows other objects to register/deregister with them for certain tasks, similar to how Unity latches onto callback methods, but in a less automated fashion. We will see an example of this in the upcoming section A global messaging system. Objects that are registered with the system during construction will want to deregister with the system during their own shutdown, and the most convenient place to do this is within its OnDestroy() method. Consequently, such objects are likely to run into the aforementioned problem, where Singletons are accidentally created during application shutdown.


To solve this problem, we need to make three changes. Firstly, we need to add an additional flag to the Singleton Component, which keeps track of its active state, and disable it at the appropriate times. This includes the Singleton's own destruction, as well as application shutdown (OnApplicationQuit() is another useful Unity callback for MonoBehaviours, which is called during this time):
The following interface definition will suffice, which only requires the implementing class to define a single method:
private bool _alive = true;
void OnDestroy() { _alive = false; }
void OnApplicationQuit() { _alive = false; }
Secondly, we should implement a way for external objects to verify the Singleton's current state:
public static bool IsAlive {
  get {
    if (__Instance == null)
      return false;
    return __Instance._alive;
  }
}
Finally, any object that attempts to call into the Singleton during its own OnDestroy() method, must first verify the state using the IsAlive property before calling Instance. For example:
public class SomeComponent : MonoBehaviour {
    void OnDestroy() {
    if (MySingletonComponent.IsAlive) {
        MySingletonComponent.Instance.SomeMethod();
    }
  }
}
This will ensure that nobody attempts to access Instance during destruction. If we don't follow this rule, then we will run into problems where instances of our Singleton object will be left behind in the Scene after returning to Edit Mode.
The irony of the Singleton Component approach is that we are using one of Unity's Find() methods to determine whether or not one of these Singleton Components already exists in the Scene before we attempt to assign the __Instance reference variable. Fortunately, this will only happen when the Singleton Component is first accessed, but it's possible that the initialization of the Singleton would not necessarily occur during Scene initialization and can therefore cost us a performance spike at a bad moment during gameplay, when this object is first instantiated and Find() gets called. The workaround for this is to have some god class confirm that the important Singletons are instantiated during Scene initialization by simply calling Instance on each one.
The downside to this approach is that if we later decide that we want more than one of these manager classes executing at once, or we wish to separate its behavior to be more modular, then there would be a lot of code that needs to change.
There are further alternatives that we can explore, such as making use of Unity's built-in bridge between script code and the Inspector interface.
public interface IUpdateable {
  void OnUpdate(float dt);
}

Next, we'll define a MonoBehaviour class, which implements this interface:
public class UpdateableMonoBehaviour : MonoBehaviour, IUpdateable 
{
  public virtual void OnUpdate(float dt) {}
}
Note that we're naming the method OnUpdate() rather than Update(). We're defining a custom version of the same concept, but we want to avoid name collisions with the standard Update() callback.
The OnUpdate() method of the UpdateableMonoBehaviour class retrieves the current delta time (dt), to spare us from a bunch of unnecessary Time.deltaTime calls. We've also made the function virtual, to allow derived classes to customize it. However, as you know, Unity automatically grabs and invokes methods defined with the name Update(), but since we're defining our own custom update with a different name, then we need to implement something that will call this method when the time is appropriate; some kind of "GameLogic" god class.
During the initialization of this Component, we should do something to notify our GameLogic object of both its existence and its destruction, so that it knows when to start and stop calling its OnUpdate() function.
In the following example, we will assume that our GameLogic class is a Singleton Component, as defined earlier in the section entitled Singleton Components, and has appropriate static functions defined for registration and deregistration (although bear in mind that it can just as easily use our messaging system!).
For MonoBehaviours to hook into this system, the most appropriate place is within Start() and OnDestroy():
void Start() {
  GameLogic.Instance.RegisterUpdateableObject(this);
}

void OnDestroy() {
  GameLogic.Instance.DeregisterUpdateableObject(this);
}


It is best to use the Start() method for this task, since using Start() means that we can be certain all other pre-existing Components will have at least had their Awake() methods called prior to this moment. This way, any critical initialization work will have already been done on the object before we start invoking updates on it.
Note that, because we're using Start() in a MonoBehaviour base class, if we define a Start() method in a derived class, then it will effectively override the base-class definition and Unity will grab the derived Start() method as a callback instead. It would, therefore, be wise to implement a virtual Initialize() method so that derived classes can override it to customize initialization behavior without interfering with the base class's task of notifying the GameLogic object of our component's existence.
For example:
void Start() {
  GameLogic.Instance.RegisterUpdateableObject(this);
  Initialize();
}

protected virtual void Initialize() {
  // derived classes should override this method for initialization code
}
We should try to make the process as automatic as possible to spare ourselves having to re-implement these tasks for each new Component we define. As soon as a class inherits from our UpdateableMonoBehaviour class, then should be secure in the knowledge that its OnUpdate() method will be called whenever it is appropriate.
Finally, we need to implement the GameLogic class. The implementation is pretty much the same whether it is a Singleton Component or a standalone Component, and whether or not it uses the MessagingSystem. Either way, our UpdateableMonoBehaviour class must register and deregister as IUpdateableObject objects, and the GameLogic class must use its own Update() callback to iterate through every registered object and call their OnUpdate() function.
Here is the class definition for the GameLogic system:
public class GameLogic : SingletonAsComponent<GameLogic> {
  public static GameLogic Instance {
    get { return ((GameLogic)_Instance); }
  set { _Instance = value; }
  }

List<IUpdateableObject> _updateableObjects = new List<IUpdateableObject>();

  public void RegisterUpdateableObject(IUpdateableObject obj) {
    if (!_Instance._updateableObjects.Contains(obj)) {
      _Instance._updateableObjects.Add(obj);
    }
  }

  public void DeregisterUpdateableObject(IUpdateableObject obj) {
    if (_Instance._updateableObjects.Contains(obj)) {
      _Instance._updateableObjects.Remove(obj);
    }
  }

  void Update() {
    float dt = Time.deltaTime;
    for(int i = 0; i < _Instance._updateableObjects.Count; ++i) {
      _Instance._updateableObjects[i].OnUpdate(dt);
    }
  }

}

If we make sure all of our custom MonoBehaviours inherit from the UpdateableMonoBehaviour class, then we've effectively replaced N invocations of the Update() callback with just one Update() callback, plus N virtual function calls. This can save us a large amount of performance overhead, because even though we're calling virtual functions, we're still keeping the overwhelming majority of update behavior inside managed code, and avoiding the native-managed bridge as much as possible.
Depending on how deep you already are into your current project, such changes can be incredibly daunting, time-consuming, and likely to introduce a lot of bugs as subsystems are updated to make use of a completely different set of dependencies. However, the benefits can outweigh the risks if time is on your side. It would be wise to do some testing on a group of objects in a Scene that is similarly designed to your current Scene files to verify if the benefits outweigh the costs.
Usage:
Many MonoBehaviours inherit from UpdateableMonoBehaviour 

UpdateableMonoBehaviour implement
public class UpdateableMonoBehaviour : MonoBehaviour, IUpdateable 
{
  public virtual void OnUpdate(float dt) {}
  void Start() {
  GameLogic.Instance.RegisterUpdateableObject(this);
  Initialize();
  }

  protected virtual void Initialize() {
  // derived classes should override this method for initialization code
  }

  void OnDestroy() {
  GameLogic.Instance.DeregisterUpdateableObject(this);
  }
}

Tuesday, April 21, 2020

Connection limit cocurrent count in iOS

https://stackoverflow.com/questions/22617233/timeout-when-issuing-too-many-afnetworking-requests

https://www.raywenderlich.com/5293-operation-and-operationqueue-tutorial-in-swift#toc-anchor-003

Creating an OperationQueue is very straightforward, as you can see. Naming your queues helps with debugging, since the names show up in Instruments or the debugger. The maxConcurrentOperationCount is set to 1 for the sake of this tutorial to allow you to see operations finishing one by one. You could leave this part out and allow the queue to decide how many operations it can handle at once — this would further improve performance.
How does the queue decide how many operations it can run at once? That’s a good question! It depends on the hardware. By default, OperationQueue does some calculation behind the scenes, decides what’s best for the particular platform it’s running on, and launches the maximum possible number of threads.
Consider the following example: Assume the system is idle and there are lots of resources available. In this case, the queue may launch eight simultaneous threads. Next time you run the program, the system may be busy with other, unrelated operations which are consuming resources. This time, the queue may launch only two simultaneous threads. Because you’ve set a maximum concurrent operations count in this app, only one operation will happen at a time.

http://blog.lightstreamer.com/2013/01/on-ios-url-connection-parallelism-and.html


Wednesday, April 1, 2020

Threading

https://forum.unity.com/threads/threads-example.135578/
http://www.albahari.com/threading/

Using different material instance cause game object not batch

  • Using different Material instances causes GameObjects not to batch together, even if they are essentially the same. The exception is shadow caster rendering.





  • Batching dynamic GameObjects has certain overhead per vertex, so batching is applied only to Meshes containing fewer than 900 vertex attributes in total.
  • If your Shader is using Vertex Position, Normal, and single UV, then you can batch up to 300 verts, If your Shader is using Vertex Position, Normal, UV0, UV1, and Tangent, then you can only batch 180 verts.
  • Note: attribute count limit might be changed in future.
  • GameObjects are not batched if they contain mirroring on the transform (for example GameObject A with +1 scale and GameObject B with –1 scale cannot be batched together).
  • Using different Material instances causes GameObjects not to batch together, even if they are essentially the same. The exception is shadow caster rendering.
  • GameObjects with lightmaps have additional renderer parameters: lightmap index and offset/scale into the lightmap. Generally, dynamic lightmapped GameObjects should point to exactly the same lightmap location to be batched.
  • Multi-pass Shaders break batching.
  • Almost all Unity Shaders support several Lights in forward rendering, effectively doing additional passes for them. The draw calls for “additional per-pixel lights” are not batched.
  • The Legacy Deferred (light pre-pass) rendering path has dynamic batching disabled because it has to draw GameObjects twice.

When you use Generic, using root motion is more expensive

https://docs.unity3d.com/Manual/MecanimPeformanceandOptimization.html

  • When you use Generic, using root motion is more expensive than not using it. If your animations don’t use root motion, make sure that you have not specified a root bone.