jyn514 / threaded-server

A stupid simple server with threading
BSD 3-Clause "New" or "Revised" License
10 stars 4 forks source link

Use mmap for large files #13

Closed jyn514 closed 5 years ago

jyn514 commented 5 years ago

See https://github.com/jyn514/crappy-server/issues/10

jyn514 commented 5 years ago

This is probably not very useful: https://stackoverflow.com/questions/45972/mmap-vs-reading-blocks#6383253. Would need to check with perf.

jyn514 commented 5 years ago

What this could help with is avoid double copies: currently perf looks like this (run again ab -n 100 -c 10 localhost:8080/data where data is binary with size 22897320 bytes:

-   92.23%     0.00%  main     main                 [.] respond (inlined)                   ▒
   - respond (inlined)                                                                      ▒
      - 52.98% handle_request (inlined)                                                     ▒
         - 52.77% _ZL10handle_urlR12request_infoRKSt3mapINSt7__cxx1112basic_stringIcSt11char▒
            - 52.59% get_file (inlined)                                                     ▒
               + 43.60% _ZNSi4readEPcl                                                      ▒
               + 7.31% ?? (inlined)                                                         ▒
               + 1.61% get_mimetype (inlined)                                               ▒
      + 38.35% __libc_send (inlined)

Note how 80% of the time is for IO: 38% for sending to the socket and 44% for reading from the file. If we could pass a pointer to an mmaped file instead of copying it, I imagine we'd get about double the speed.

jyn514 commented 5 years ago

Tested this both ways; this has a speedup of 48%! Counting this as a resounding success.

With std::ifstream.read:

$ ab -n 1000 -c 100 localhost:8080/data
This is ApacheBench, Version 2.3 <$Revision: 1807734 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking localhost (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests

Server Software:        crappy_server/0.0.1
Server Hostname:        localhost
Server Port:            8080

Document Path:          /data
Document Length:        22897320 bytes

Concurrency Level:      100
Time taken for tests:   17.691 seconds
Complete requests:      1000
Failed requests:        0
Total transferred:      22897536000 bytes
HTML transferred:       22897320000 bytes
Requests per second:    56.53 [#/sec] (mean)
Time per request:       1769.084 [ms] (mean)
Time per request:       17.691 [ms] (mean, across all concurrent requests)
Transfer rate:          1263980.68 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0   10  90.7      1    1019
Processing:   445 1744 357.0   1763    3326
Waiting:       10  178 364.6     25    1772
Total:        446 1753 381.1   1764    3456

Percentage of the requests served within a certain time (ms)
  50%   1764
  66%   1773
  75%   1780
  80%   1790
  90%   1903
  95%   2403
  98%   2992
  99%   3235
 100%   3456 (longest request)

With mmap:

This is ApacheBench, Version 2.3 <$Revision: 1807734 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking localhost (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests

Server Software:        crappy_server/0.0.1
Server Hostname:        localhost
Server Port:            8080

Document Path:          /data
Document Length:        22897320 bytes

Concurrency Level:      100
Time taken for tests:   10.887 seconds
Complete requests:      1000
Failed requests:        0
Total transferred:      22897533000 bytes
HTML transferred:       22897320000 bytes
Requests per second:    91.86 [#/sec] (mean)
Time per request:       1088.663 [ms] (mean)
Time per request:       10.887 [ms] (mean, across all concurrent requests)
Transfer rate:          2053976.51 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0   29 165.4      1    1021
Processing:   367 1046 114.0   1077    1287
Waiting:        0   18  62.9      1     526
Total:        368 1074 207.9   1078    2302

Percentage of the requests served within a certain time (ms)
  50%   1078
  66%   1082
  75%   1085
  80%   1094
  90%   1100
  95%   1105
  98%   2093
  99%   2100
 100%   2302 (longest request)
jyn514 commented 5 years ago

https://github.com/jyn514/crappy-server/commit/c64790077f72f11f5475e5c5e849f6eeeb1237ac