I could not find description of how PCC include addresses and ports in its hash, but from my testing it appears that they they include port numbers inside data to be hashed, something like:
PCC_hash= Hash( seed? & src_addr & dst_addr & src_port & dst_port) , where ‘&’ is string concatenation
Problem with that approach is when we want to use PCC for load balancing (most obvious use). When we use PCC to load balance over two connections, most logical advantages should be for processes that open multiple connections to download or upload something , and those multiple connections have all other data same except for src_port , which tend to increment by one ( so for example, if you use speedtest.net , it will open connection on 6 consecutive ports ).
If we have two similar links, in above example we would like Speedtest.net to use 3 connections on one ISP link and 3 connections on another. We would use something like per-connection-classifier=both-addresses-and-ports:2/0 to ensure src_port is included in hash.
So, what is the problem? Due to how Mikrotik calculate hash, very often N connections would NOT be split evenly with N/2 going to ISP1 and N/2 going to ISP2. In our speedtest case, very often we would have 4 connections to one ISP and 2 to other. That is because both even and odd ports have equal chance to produce even hash. So when speedtest uses ports 52900, 52901,52902,52903,52904,52905 ( 3 even and 3 odd), hash function can end up with 4 odd and 2 even numbers, or even all odd numbers in rare cases - and then all connections would go over single ISP. But in many cases it would split unevenly.
This problem gets only worse for 3 or more connections - chance that PCC will split 6 consecutive source ports evenly across 3 outgoing ISP links (per-connection-classifier=both-addresses-and-ports:3/0 , :3/1, :3/2 ) is even lower.
Suggested solution: Change PCC_hash to add ports after hash is calculated ( or at least add src_port afterwards). For example:
Better_PCC_hash= Hash( seed? & src_addr & dst_addr & dst_port) + src_port , where ‘+’ is integer addition
In this way, when we have source ports as even-odd-even-odd-even-odd ( like they are almost always when same app use multiple connections ) , we are guaranteed to have similar alternating odd/even hashes ( with guaranteed 3 odd and 3 even hashes ). Same logic goes for 3 or more connections - hash would be evenly split across links if source ports were consecutive.