I have a Git repository in a shared folder on a Windows PC which I am accessing with an UNC path, e.g.
git clone //server/share/MyRepo.git
When I fetch changes from this repository over a VPN from home it takes a very long time for git-upload-pack.exe
to run. I realise that there is no server (as such) involved and my local PC is running all of the executables.
The name of git-upload-pack.exe
suggests to me that my local PC is reading files from the remote file share in order to upload them somewhere, but that would be to itself, which makes no sense. This in turn leads me to think that the fetch
is nowhere near as performant as it could be. It's like the local machine is doing all the work to cut down the data to transfer, but to do that it has to transfer all the data.
Can anyone shed some light on how this works? Is performance as good as possible without running a true Git server via SSH or whatever at the remote end, or are files being transferred back and forth unnecessarily?
With git 2.1 (August 2014), this fetch should be much quicker: an old 2012 fix is finally being integrated into git.
See commit 76e7c8a by (theoleblond
)
compat/poll
: sleep 1 millisecond to avoid busy wait
SwitchToThread()
only gives away the rest of the current time slice to another thread in the current process. So if the thread that feeds the file decscriptor we're polling is not in the current process, we get busy-waiting.I played around with this quite a bit. After trying some more complex schemes, I found that what worked best is to just sleep 1 millisecond between iterations. Though it's a very short time, it still completely eliminates the busy wait condition, without hurting perf.
There code uses
SleepEx(1, TRUE)
to sleep.
See this page for a good discussion of why that is better than callingSwitchToThread
, which is what was used previously:Note that calling
SleepEx(0, TRUE)
does not solve the busy wait.The most striking case was when testing on a UNC share with a large repo, on a single CPU machine.
Without the fix, it took 4 minutes 15 seconds, and with the fix it took just 1:08! I think it's becausegit-upload-pack
's busy wait was eating the CPU away from the git process that's doing the real work.
With multi-proc, the timing is not much different, but tons of CPU time is still wasted, which can be a killer on a server that needs to do bunch of other things.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With