winlin

fix #249, cache the chunk headers info to +5% or +10% performance. 2.0.51

@@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 // current release version 31 // current release version
32 #define VERSION_MAJOR 2 32 #define VERSION_MAJOR 2
33 #define VERSION_MINOR 0 33 #define VERSION_MINOR 0
34 -#define VERSION_REVISION 50 34 +#define VERSION_REVISION 51
35 // server info. 35 // server info.
36 #define RTMP_SIG_SRS_KEY "SRS" 36 #define RTMP_SIG_SRS_KEY "SRS"
37 #define RTMP_SIG_SRS_ROLE "origin/edge server" 37 #define RTMP_SIG_SRS_ROLE "origin/edge server"
@@ -79,5 +79,12 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -79,5 +79,12 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
79 */ 79 */
80 #define SRS_PERF_SEND_MSGS_CACHE 500 80 #define SRS_PERF_SEND_MSGS_CACHE 500
81 81
  82 +/**
  83 +* how many chunk stream to cache, [0, N].
  84 +* to imporove about 10% performance when chunk size small, and 5% for large chunk.
  85 +* @see https://github.com/winlinvip/simple-rtmp-server/issues/249
  86 +*/
  87 +#define SRS_PERF_CHUNK_STREAM_CACHE 16
  88 +
82 #endif 89 #endif
83 90
@@ -417,6 +417,16 @@ SrsProtocol::SrsProtocol(ISrsProtocolReaderWriter* io) @@ -417,6 +417,16 @@ SrsProtocol::SrsProtocol(ISrsProtocolReaderWriter* io)
417 417
418 warned_c0c3_cache_dry = false; 418 warned_c0c3_cache_dry = false;
419 auto_response_when_recv = true; 419 auto_response_when_recv = true;
  420 +
  421 + cs_cache = new SrsChunkStream*[SRS_PERF_CHUNK_STREAM_CACHE];
  422 + for (int cid = 0; cid < SRS_PERF_CHUNK_STREAM_CACHE; cid++) {
  423 + SrsChunkStream* cs = new SrsChunkStream(cid);
  424 + // set the perfer cid of chunk,
  425 + // which will copy to the message received.
  426 + cs->header.perfer_cid = cid;
  427 +
  428 + cs_cache[cid] = cs;
  429 + }
420 } 430 }
421 431
422 SrsProtocol::~SrsProtocol() 432 SrsProtocol::~SrsProtocol()
@@ -448,6 +458,13 @@ SrsProtocol::~SrsProtocol() @@ -448,6 +458,13 @@ SrsProtocol::~SrsProtocol()
448 free(out_iovs); 458 free(out_iovs);
449 out_iovs = NULL; 459 out_iovs = NULL;
450 } 460 }
  461 +
  462 + // free all chunk stream cache.
  463 + for (int i = 0; i < SRS_PERF_CHUNK_STREAM_CACHE; i++) {
  464 + SrsChunkStream* cs = cs_cache[i];
  465 + srs_freep(cs);
  466 + }
  467 + srs_freep(cs_cache);
451 } 468 }
452 469
453 void SrsProtocol::set_auto_response(bool v) 470 void SrsProtocol::set_auto_response(bool v)
@@ -1102,17 +1119,30 @@ int SrsProtocol::recv_interlaced_message(SrsMessage** pmsg) @@ -1102,17 +1119,30 @@ int SrsProtocol::recv_interlaced_message(SrsMessage** pmsg)
1102 // get the cached chunk stream. 1119 // get the cached chunk stream.
1103 SrsChunkStream* chunk = NULL; 1120 SrsChunkStream* chunk = NULL;
1104 1121
1105 - if (chunk_streams.find(cid) == chunk_streams.end()) {  
1106 - chunk = chunk_streams[cid] = new SrsChunkStream(cid);  
1107 - // set the perfer cid of chunk,  
1108 - // which will copy to the message received.  
1109 - chunk->header.perfer_cid = cid;  
1110 - srs_verbose("cache new chunk stream: fmt=%d, cid=%d", fmt, cid);  
1111 - } else {  
1112 - chunk = chunk_streams[cid]; 1122 + // use chunk stream cache to get the chunk info.
  1123 + // @see https://github.com/winlinvip/simple-rtmp-server/issues/249
  1124 + if (cid < SRS_PERF_CHUNK_STREAM_CACHE) {
  1125 + // chunk stream cache hit.
  1126 + srs_verbose("cs-cache hit, cid=%d", cid);
  1127 + // already init, use it direclty
  1128 + chunk = cs_cache[cid];
1113 srs_verbose("cached chunk stream: fmt=%d, cid=%d, size=%d, message(type=%d, size=%d, time=%"PRId64", sid=%d)", 1129 srs_verbose("cached chunk stream: fmt=%d, cid=%d, size=%d, message(type=%d, size=%d, time=%"PRId64", sid=%d)",
1114 chunk->fmt, chunk->cid, (chunk->msg? chunk->msg->size : 0), chunk->header.message_type, chunk->header.payload_length, 1130 chunk->fmt, chunk->cid, (chunk->msg? chunk->msg->size : 0), chunk->header.message_type, chunk->header.payload_length,
1115 chunk->header.timestamp, chunk->header.stream_id); 1131 chunk->header.timestamp, chunk->header.stream_id);
  1132 + } else {
  1133 + // chunk stream cache miss, use map.
  1134 + if (chunk_streams.find(cid) == chunk_streams.end()) {
  1135 + chunk = chunk_streams[cid] = new SrsChunkStream(cid);
  1136 + // set the perfer cid of chunk,
  1137 + // which will copy to the message received.
  1138 + chunk->header.perfer_cid = cid;
  1139 + srs_verbose("cache new chunk stream: fmt=%d, cid=%d", fmt, cid);
  1140 + } else {
  1141 + chunk = chunk_streams[cid];
  1142 + srs_verbose("cached chunk stream: fmt=%d, cid=%d, size=%d, message(type=%d, size=%d, time=%"PRId64", sid=%d)",
  1143 + chunk->fmt, chunk->cid, (chunk->msg? chunk->msg->size : 0), chunk->header.message_type, chunk->header.payload_length,
  1144 + chunk->header.timestamp, chunk->header.stream_id);
  1145 + }
1116 } 1146 }
1117 1147
1118 // chunk stream message header 1148 // chunk stream message header
@@ -205,6 +205,12 @@ private: @@ -205,6 +205,12 @@ private:
205 */ 205 */
206 std::map<int, SrsChunkStream*> chunk_streams; 206 std::map<int, SrsChunkStream*> chunk_streams;
207 /** 207 /**
  208 + * cache some frequently used chunk header.
  209 + * cs_cache, the chunk stream cache.
  210 + * @see https://github.com/winlinvip/simple-rtmp-server/issues/249
  211 + */
  212 + SrsChunkStream** cs_cache;
  213 + /**
208 * bytes buffer cache, recv from skt, provide services for stream. 214 * bytes buffer cache, recv from skt, provide services for stream.
209 */ 215 */
210 SrsFastBuffer* in_buffer; 216 SrsFastBuffer* in_buffer;