17f58c8 (parent of d2a7d7c)
Transfer rate: 4103 KB/sec (52429310 bytes in 12 seconds)
Transfer rate: 4121 KB/sec (52429310 bytes in 12 seconds)
Transfer rate: 4067 KB/sec (52429310 bytes in 13 seconds)
Transfer rate: 4078 KB/sec (52429310 bytes in 13 seconds)
Transfer rate: 4074 KB/sec (52429310 bytes in 13 seconds)
Transfer rate: 4100 KB/sec (52429310 bytes in 12 seconds)
d2a7d7c ("multi: implement wait using winsock events")
Transfer rate: 503 KB/sec (52429310 bytes in 102 seconds)
Transfer rate: 503 KB/sec (52429310 bytes in 102 seconds)
Transfer rate: 971 KB/sec (52429310 bytes in 53 seconds)
Transfer rate: 503 KB/sec (52429310 bytes in 102 seconds)
Transfer rate: 507 KB/sec (52429310 bytes in 101 seconds)
Transfer rate: 503 KB/sec (52429310 bytes in 102 seconds)
curl 7.73.0-DEV (i386-pc-win32) libcurl/7.73.1-DEV OpenSSL/1.0.2t nghttp2/1.40.0
The 1 second delay is coming from this call to WSAWaitForMultipleEvents in multi_wait:
diff --git a/lib/multi.c b/lib/multi.c
index c8bba47..d71a573 100644
--- a/lib/multi.c
+++ b/lib/multi.c
@@ -1275,7 +1275,17 @@ static CURLMcode Curl_multi_wait(struct Curl_multi *multi,
#ifdef USE_WINSOCK
if(already_writable > 0)
timeout_ms = 0;
- WSAWaitForMultipleEvents(1, &multi->wsa_event, FALSE, timeout_ms, FALSE);
+ {
+ DWORD ret;
+ struct curltime before, after;
+ before = Curl_now();
+ ret = WSAWaitForMultipleEvents(1, &multi->wsa_event, FALSE, timeout_ms,
+ FALSE);
+ after = Curl_now();
+ fprintf(stderr,
+ "WSAWaitForMultipleEvents timeout_ms: %d, ret: %d, elapsed: %I64d\n",
+ timeout_ms, ret, Curl_timediff(after, before));
+ }
#else
int pollrc = Curl_poll(ufds, nfds, timeout_ms);
#endif
WSAWaitForMultipleEvents timeout_ms: 0, ret: 258, elapsed: 0
WSAWaitForMultipleEvents timeout_ms: 0, ret: 258, elapsed: 0
WSAWaitForMultipleEvents timeout_ms: 0, ret: 258, elapsed: 0
WSAWaitForMultipleEvents timeout_ms: 0, ret: 258, elapsed: 0
WSAWaitForMultipleEvents timeout_ms: 0, ret: 258, elapsed: 0
WSAWaitForMultipleEvents timeout_ms: 0, ret: 258, elapsed: 0
WSAWaitForMultipleEvents timeout_ms: 0, ret: 258, elapsed: 0
WSAWaitForMultipleEvents timeout_ms: 0, ret: 258, elapsed: 0
WSAWaitForMultipleEvents timeout_ms: 0, ret: 258, elapsed: 0
WSAWaitForMultipleEvents timeout_ms: 0, ret: 258, elapsed: 0
WSAWaitForMultipleEvents timeout_ms: 0, ret: 258, elapsed: 0
WSAWaitForMultipleEvents timeout_ms: 0, ret: 258, elapsed: 0
WSAWaitForMultipleEvents timeout_ms: 0, ret: 258, elapsed: 0
WSAWaitForMultipleEvents timeout_ms: 0, ret: 258, elapsed: 0
WSAWaitForMultipleEvents timeout_ms: 0, ret: 258, elapsed: 0
WSAWaitForMultipleEvents timeout_ms: 0, ret: 258, elapsed: 0
WSAWaitForMultipleEvents timeout_ms: 0, ret: 258, elapsed: 0
WSAWaitForMultipleEvents timeout_ms: 1000, ret: 0, elapsed: 2
WSAWaitForMultipleEvents timeout_ms: 1000, ret: 258, elapsed: 1000
4% uploaded...WSAWaitForMultipleEvents timeout_ms: 0, ret: 258, elapsed: 0
WSAWaitForMultipleEvents timeout_ms: 0, ret: 258, elapsed: 0
WSAWaitForMultipleEvents timeout_ms: 0, ret: 258, elapsed: 0
WSAWaitForMultipleEvents timeout_ms: 0, ret: 258, elapsed: 0
WSAWaitForMultipleEvents timeout_ms: 0, ret: 258, elapsed: 0
WSAWaitForMultipleEvents timeout_ms: 0, ret: 258, elapsed: 0
WSAWaitForMultipleEvents timeout_ms: 0, ret: 258, elapsed: 0
WSAWaitForMultipleEvents timeout_ms: 0, ret: 258, elapsed: 0
WSAWaitForMultipleEvents timeout_ms: 0, ret: 258, elapsed: 0
WSAWaitForMultipleEvents timeout_ms: 0, ret: 258, elapsed: 0
WSAWaitForMultipleEvents timeout_ms: 0, ret: 258, elapsed: 0
WSAWaitForMultipleEvents timeout_ms: 0, ret: 258, elapsed: 0
WSAWaitForMultipleEvents timeout_ms: 0, ret: 258, elapsed: 0
WSAWaitForMultipleEvents timeout_ms: 0, ret: 258, elapsed: 0
WSAWaitForMultipleEvents timeout_ms: 0, ret: 258, elapsed: 0
WSAWaitForMultipleEvents timeout_ms: 0, ret: 258, elapsed: 0
WSAWaitForMultipleEvents timeout_ms: 0, ret: 258, elapsed: 0
WSAWaitForMultipleEvents timeout_ms: 0, ret: 258, elapsed: 0
WSAWaitForMultipleEvents timeout_ms: 1000, ret: 0, elapsed: 2
WSAWaitForMultipleEvents timeout_ms: 1000, ret: 258, elapsed: 1000
6% uploaded...WSAWaitForMultipleEvents timeout_ms: 0, ret: 258, elapsed: 0
WSAWaitForMultipleEvents timeout_ms: 0, ret: 258, elapsed: 0
WSAWaitForMultipleEvents timeout_ms: 0, ret: 258, elapsed: 0
WSAWaitForMultipleEvents timeout_ms: 0, ret: 258, elapsed: 0
WSAWaitForMultipleEvents timeout_ms: 0, ret: 258, elapsed: 0
WSAWaitForMultipleEvents timeout_ms: 0, ret: 258, elapsed: 0
WSAWaitForMultipleEvents timeout_ms: 0, ret: 258, elapsed: 0
WSAWaitForMultipleEvents timeout_ms: 0, ret: 258, elapsed: 0
WSAWaitForMultipleEvents timeout_ms: 0, ret: 258, elapsed: 0
WSAWaitForMultipleEvents timeout_ms: 0, ret: 258, elapsed: 0
WSAWaitForMultipleEvents timeout_ms: 0, ret: 258, elapsed: 0
WSAWaitForMultipleEvents timeout_ms: 0, ret: 258, elapsed: 0
WSAWaitForMultipleEvents timeout_ms: 0, ret: 258, elapsed: 0
WSAWaitForMultipleEvents timeout_ms: 0, ret: 258, elapsed: 0
WSAWaitForMultipleEvents timeout_ms: 0, ret: 258, elapsed: 0
WSAWaitForMultipleEvents timeout_ms: 0, ret: 258, elapsed: 0
WSAWaitForMultipleEvents timeout_ms: 0, ret: 258, elapsed: 0
WSAWaitForMultipleEvents timeout_ms: 0, ret: 258, elapsed: 0
WSAWaitForMultipleEvents timeout_ms: 1000, ret: 0, elapsed: 4
WSAWaitForMultipleEvents timeout_ms: 1000, ret: 258, elapsed: 1000
8% uploaded...WSAWaitForMultipleEvents timeout_ms: 0, ret: 258, elapsed: 0
If that WSAWaitForMultipleEvents line is commented out then the transfer completes in the expected time (but then of course eats CPU in the interim since there's no poll wait).
User Jeffrey McKay has reported on the curl-library mailing list that after upgrading to 7.73.0 the upload performance decreased drastically. What was typically a 10 second upload took over 5 minutes.
(Click to expand his report) In summary, he describes it as "large chunks of data seem to be taking 1 second to upload".
I am able to reproduce in Windows and bisected it to d2a7d7c with the PostUpload example.
The 1 second delay is coming from this call to WSAWaitForMultipleEvents in multi_wait:
curl/lib/multi.c
Lines 1278 to 1282 in 315ee3f
Debug code:
Debug output (ret 258 is WSA_WAIT_TIMEOUT):
If that WSAWaitForMultipleEvents line is commented out then the transfer completes in the expected time (but then of course eats CPU in the interim since there's no poll wait).
According to the commit message in d2a7d7c, a previous version of that commit patch would erroneously wait the full timeout for the socket to become writable. It looks like that issue may not be fully fixed?
Ref: #5397
Ref: #5631
Ref: #5634
/cc @rcombs @mback2k @MarcelRaad @Togtja @ngg @rmja