How to code scoreboard for out-of-order transactions between golden C model and RTL?

I’ve a UVM test env where both golden C++ model and RTL are instantiated. In some cases my C++ model and RTL outputs will go out of order as C++ model is not cycle accurate. For in-order outputs, I just have infinite queues in my scoreboard. Whenever I see output in RTL interface, I try to match it with the head of c++ model-output queue. Here the assumption is outputs from c++ model will always come before RTL output as there is no notion of time in c++ model.

However in-order output between golden model and RTL is not guaranteed (as an example, arbiter). In that case, what is the standard way to write scoreboard and checking codes in UVM?

Implement an index_id() function that returns a value that is used as a key for the associative array. If an entry with this key already exists in the associative array, it means that a transaction previously arrived from the other stream, and the transactions are compared. If no key exists, then this transaction is added to associative array.

Cookbook:
https://verificationacademy.com/cookbook/scoreboards#Comparing_transactions_out-of-order