perf: add threading capability to perfbdiff
Since we are releasing the GIL during diffing, it is interesting to see how a
thread pool would perform on diffing. We add a new `--threads` argument to
commands. Synchronizing the thread pool is a bit complex because we want to be
able to reuse it from one run to another.
On my computer (i7 with 4 cores + hyperthreading), I get the following data for
about 12000 revisions:
threads wall comb wall gain comb overhead
none 31.596715 31.59 0.00% 0.00%
1 31.621228 31.62 -0.08% 0.09%
2 16.406202 32.8 48.08% 3.83%
3 11.598334 34.76 63.29% 10.03%
4 9.205421 36.77 70.87% 16.40%
5 8.517604 42.51 73.04% 34.57%
6 7.94645 47.58 74.85% 50.62%
7 7.434972 51.92 76.47% 64.36%
8 7.070638 55.34 77.62% 75.18%
Compared to the feature disabled (threads=0), the overhead is negligible with
the threading code (threads=1), and the gain is already 48% with two threads.
-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEA2Ugt7jQrD+u+JtIfXZpVepzOAufcX4CMoHV95qZXZml2juGp
x3T7wjQPB/IPoOpRG9CoCaekKK+bIqQX1qNuiUa2CsqchNQcua2js5DTttmRYC+f
wHaQc0UY1QKe/0r8NFX1XoeIWfuL+0UAERoI1zmhu9px5326C7PoyBPIubT0ejLV
LfciFgyHDmqvYGu6cUBpNFrAi8csPNGcyie1Axh0wZ/9jvHdN+iGmaV9GZObGv0G
ZpbWlJm8fG+mH1qMFYA6mnknJbEBBTnV0IWdGJalGnz+5GfCvhxzYcEWmLDeO/7F
NrWMVT9L8Ky65cygCeJ4lEW1XB1w/6rQYjaSnwIDAQABAoIBAAwDAH8FpUfJCYcN
4KwFByqzFnR0qusgqSWJuT8R/QztUZ+OfBtJrU1MIXSX/iMwMPGvtEpsWRfitVnR
5nt4J3kxTokEMGjrbPca0Uzw+bNHDdFacKNsKookzL2h2nZUh+LAycLDDVekH1Xx
t5I6dTiot/cxmVBp0+ontPuylEsnyrQio6eljBfPzxBdRp2lkiymKf3jvbGXRnZ4
jSFTRuUlbnVbZ3CKnFPU+d5tvn2nEwU/DVbGpJNZAPl99Q0XUcNF3AtGlwGMvi0X
azcIIOn+swLjn+U2S6i3K234ItYS5I+c9Xi+9DO4fuVko+CQ8PWXP2HdAze7DENc
zADmd0kCgYEA7nN+qUFAmMOcRE8nSNLt7mcwq6fYQ1MVGikCIXn/PI/wfEqY0lws
ZhwykBXog0S7PzYkR3LcDOqN0wDcdJ3K4c/a6Z6IqbXMgxaosYfHCCMtdhy0g0F2
ek0SaY3WQhpFRIG19hvB+ZJSc7JQt+TaXeb8HM1452kmOLpfQGiqqTsCgYEA6UXZ
bI7c2jO1X+rWF2tZfZdtdeVrIVcm8BunF7ETC4iK/iH2phRQQAh4TFZm6wkX57Tv
LKDGxmohFlEK7FOtSCeSSVfkvZYRBuHOYcwBgBr1XzXXjHcMoyr0+LflZysht151
9F0hJwdGQZrivZnv9clJ632RlgE4XlPGskQhRe0CgYEAxVGdhsIQilmUfpJhl8m0
SovpoqKKO2wNElDNCpbBt4QFJVU1kR3lP7olvUXj2nyN1okfDGDn52hRZEJaK8ZH
lQVDyf7+aDGgwvmFLyOEeB9kB1FJrzQErsAIdICCxMCogUA1KytdIQEMaeEtGn+u
k/YIumztl9FTZ64SFGKIlvECgYEA25Kb7csrp1g0yWxKyRCK0+TNa8Pe6ysVw7zD
s1FCFAEak8t0Vy+Xui4+zdwmU+XjUn7FAsTzVaBgNJlkJr88xEY7ND4/WRUAQfIa
SYO1hdfaTxxnIBiPFKdCnzq5/DplKi0H6lQe+JWoU+hutPlJHZmysq8ncoMDhAZn
aTUn/KECgYEAvxGaWt4Fn2tRrHeaG0qT+nMBxd8cTiFInOcYDeS/FlQo3DTDK2Ai
qLBa4DinnGN2hSKwnN3R5R2VRxk4I6+ljG0yuNBhJBcAgAFpnHfkuY1maQJB+1xY
A07WcM4J3yuPfjcDkipNFQa4Y8oJCaS2yiOPvlUfNQrCLAV+YqHZiiQ=
-----END RSA PRIVATE KEY-----