Search Unity

Unitysynchronizationcontext.executetasks() causes low game performance

Discussion in 'Scripting' started by travakin, Jun 18, 2019.

  1. travakin

    travakin

    Joined:
    Apr 20, 2012
    Posts:
    7
    Hi, I am developing a multiplayer game with a custom built networking system using C# sockets. Recently, I tried adding several players to the game and my tickrate tanked from 60 to 10 or 15 after about 6 players (I am aiming for 16-24 players total). The profiler is saying this is caused by a function called unitysynchronizationcontext.executetasks(), which I have never heard of before and can't seem to find much about it on Google. What can I do about this?

    Here is my profiler window:

    upload_2019-6-17_19-58-27.png

    The meat of the server code is a basic async/await function which takes Packet objects from a UDP socket and routes them to a parsing function to be interpreted by the game logic.

    Code (CSharp):
    1.         private async void UdpServerData(IAsyncResult result) {
    2.  
    3.             UdpClient socket = result.AsyncState as UdpClient;
    4.  
    5.             socket.BeginReceive(new AsyncCallback(UdpServerData), socket);
    6.  
    7.             IPEndPoint clientEndPoint = new IPEndPoint(IPAddress.Any, 0);
    8.  
    9.             byte[] receivedBytes = new byte[0];
    10.  
    11.             try {
    12.                 receivedBytes = udpClient.EndReceive(result, ref clientEndPoint);
    13.                 currentInboundPacketTotal += 1;
    14.                 currentInboundBytesTotal += receivedBytes.Length;
    15.             }
    16.             catch (SocketException se) {
    17.  
    18.                 Debug.LogError("Unable to read socket stream!");
    19.             }
    20.  
    21.             NetworkConnection newConnection = new NetworkConnection(clientEndPoint, DateTime.Now);
    22.  
    23.             int idx = Array.IndexOf(clientConnections, newConnection);
    24.             if (idx > -1) {
    25.  
    26.                 newConnection = clientConnections[idx];
    27.             }
    28.  
    29.             Packet readPacket = Converters.DeserializePacket(receivedBytes);
    30.  
    31.             if (readPacket != null && readPacket.priority == Packet.PRIORITY_HIGH) {
    32.  
    33.                 PacketPriorityAck ackPacket = new PacketPriorityAck();
    34.                 ackPacket.responseId = readPacket.packetId;
    35.  
    36.                 await SendPacket(ackPacket, newConnection);
    37.  
    38.                 if (HighPriorityMessageLog.highPriorityMessageRecords.ContainsKey(readPacket.packetId)) {
    39.  
    40.                     return;
    41.                 }
    42.  
    43.                 HighPriorityRequestRecord record = new HighPriorityRequestRecord();
    44.                 record.id = readPacket.packetId;
    45.                 record.timeStamp = DateTime.Now;
    46.  
    47.                 HighPriorityMessageLog.highPriorityMessageRecords.TryAdd(readPacket.packetId, record);
    48.             }
    49.  
    50.             if (readPacket != null) {
    51.  
    52.                 parsers[readPacket.type](readPacket, newConnection);
    53.             }
    54.         }
    Thanks!
     
    AbleArcher and jason-vreps like this.
  2. justinvirtualitics

    justinvirtualitics

    Joined:
    Oct 19, 2016
    Posts:
    1
    Bump! I am having a similar issue using GRPC for network connections. It similarly uses async Tasks.
     
  3. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,751
  4. BeregAlto

    BeregAlto

    Joined:
    Aug 5, 2018
    Posts:
    14
    Bump. Any luck with that bug?
     
  5. babayandbabay

    babayandbabay

    Joined:
    Aug 2, 2016
    Posts:
    2
    Bump, anyone?? Having 2Kb allocation per frame by this calls
     
  6. _geo__

    _geo__

    Joined:
    Feb 26, 2014
    Posts:
    1,347
    To support the "async" keyword Unity implements a custom Synchronization context (source). That context executing some of your async methods is what you see in the profiler. Checking your async methods for memory leaks might be a good starting point.

    Async creates state machines in the back. I am not sure if there is some inherent garbage created due to that. From what I understand async creates classes in debug mode and structs in release mode. My assumption would be that even if there was some garbage creation involved it would be highly optimized by the Runtime/Compiler.
     
    Last edited: Jul 28, 2022
    alexandr13568, odoluca and Bunny83 like this.