Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Q: Performance warning #307

Open
angelskieglazki opened this issue Jan 12, 2024 · 0 comments
Open

Q: Performance warning #307

angelskieglazki opened this issue Jan 12, 2024 · 0 comments

Comments

@angelskieglazki
Copy link

angelskieglazki commented Jan 12, 2024

Hello!
Are these messages normal? It seems to me that I am doing something wrong.

...
  0.000000 Waited 2.2ms for SteamNetworkingSockets lock
  0.000000 SteamNetworkingSockets lock held for 6.4ms.  (Performance warning.)  ServiceThread,CSteamNetworkConnectionBase::Think(x2),SNP_SendPacket(x2),SendUDPacket(x2)
This is usually a symptom of a general performance problem such as thread starvation.
  0.000000 SteamNetworkingSockets lock held for 6.8ms.  (Performance warning.)  ServiceThread,RecvUDPPacket,CSteamNetworkConnectionBase::Think,SNP_SendPacket,SendUDPacket
This is usually a symptom of a general performance problem such as thread starvation.
  0.000000 Waited 3.7ms for SteamNetworkingSockets lock
  0.000000 Waited 2.4ms for SteamNetworkingSockets lock
  ...
  0.000000 SteamNetworkingSockets lock held for 5.7ms.  (Performance warning.)  ServiceThread,CSteamNetworkConnectionBase::Think(x9),SNP_SendPacket(x18),SendUDPacket(x18)
This is usually a symptom of a general performance problem such as thread starvation
  0.000000 SteamNetworkingSockets lock held for 8.8ms.  (Performance warning.)  ServiceThread
This is usually a symptom of a general performance problem such as thread starvation.
  0.000000 SteamNetworkingSockets lock held for 9.1ms.  (Performance warning.)  SendMessages
This is usually a symptom of a general performance problem such as thread starvation.
  0.000000 SteamNetworkingSockets lock held for 32.5ms.  (Performance warning.)  ServiceThread,CSteamNetworkConnectionBase::Think(x8),SNP_SendPacket(x8),SendUDPacket(x8)
This is usually a symptom of a general performance problem such as thread starvation.
  0.000000 SteamNetworkingSockets lock held for 32.9ms.  (Performance warning.)  SendMessages
This is usually a symptom of a general performance problem such as thread starvation.
  0.000000 SteamNetworkingSockets lock held for 20.7ms.  (Performance warning.)  ServiceThread
This is usually a symptom of a general performance problem such as thread starvation.
  0.000000 SteamNetworkingSockets lock held for 20.8ms.  (Performance warning.)  SendMessages
This is usually a symptom of a general performance problem such as thread starvation
...

I’ll describe a little how my game server works, there are two threads from which the GNS api is called.

  1. Server network thread.
void server_network_thread() {
  while (Is_running_) {
    auto till = clock->nowMilliseconds() + THREAD_SLEEP_DELAY;
    processIncomingMessages();
    pollConnectionStateChanges();
    sendMessages(0);
    std::this_thread::sleep_until(till);
  }
}
 processIncomingMessages(); - contains reading messages one by one using the function ReceiveMessagesOnPollGroup(...);
 pollConnectionStateChanges(); - calling SteamNetworkingSockets()->RunCallbacks();
 sendMessages(0); - generates messages from the send queue and sends them through the function SteamNetworkingSockets()->SendMessages(...);
 THREAD_SLEEP_DELAY = 1ms or 5ms, does not affect the final result

so this thread is running and then we will get a message about creating a game room:

  1. Room thread - a little more complicated, typical game loop:
class RoomTicker {
public:
  RoomTicker() = default;
  ~RoomTicker() = default;
  void inc() { ++currentTick_; }
  int64_t currentTick() const { return currentTick_;}
  int64_t currentTickTime() const { return (int64_t)((double)(currentTick_ * 1000) / TICKS_PER_SECOND); }
  static constexpr float deltaTime() { return 1000. / TICKS_PER_SECOND; }
  static constexpr double TICKS_PER_SECOND = 40.;
private:
  int64_t currentTick_ = 0;
};

void gameroom_thread() {
  room_start_time = clock->nowMilliseconds();

  while (Is_running_) {
    int64_t room_time = clock->nowMilliseconds() - room_start_time;
    readAllMessages();
    processAllMessages();

    int passed_ticks = 0;
    for (; ticker.currentTickTime() <= room_time; ticker.inc()) {
      ++passed_ticks;
      {
        // SOME GAME LOGIC
        // SOME GAME LOGIC
        // SOME GAME LOGIC
      }
      sendMessages(ticker_.currentTick());
    }

    if (passed_ticks <= 1) {
      const auto till = std::chrono::time_point<std::chrono::system_clock>(
                std::chrono::milliseconds(room_start_time + ticker.currentTickTime()));
      std::this_thread::sleep_until(till);
    }
  }
}
readAllMessages(); - here I read as many messages from the socket as I can. I set the constant to 200 messages. I read the messages, put them in a recvQueue, and so on until SteamNetworkingSockets()->ReceiveMessagesOnPollGroup(roomPollGroup, messages_array, 200); will not return 0.
processAllMessages - process all commands and messages that were received
// SOME GAME LOGIC - game logic. We create messages and fill the sending queue.
sendMessages(ticker_.currentTick()); -  send all messages from sendQueue via  SteamNetworkingSockets()->SendMessages(...);

Сlients send reliable messages with positions about 50 times per second. Starting from 30+ players, lags begin and warnings begin to spam.
I started thinking and this is what I came up with: if 30 players are connected and they send 50 messages per second, then 1500 times per second I call GNS-api. Since I am not calling it from a network thread, GNS-mutexes will be locked there, which is what I see (0.000000 Waited 2.4ms for SteamNetworkingSockets lock ... and so on).
Perhaps I should send and receive messages in only one network thread, then the thread-contention will be minimal and the wait on the GNS mutexes will also be minimal. And the room threads will communicate with the network thread through queues, which I will somehow exchange under my mutex.

In general, I want to consult with you :)

regards, max

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant