From 60bc9c2aa0b1c95b350814affffd528d23ecc60b Mon Sep 17 00:00:00 2001 From: winlin Date: Thu, 4 Dec 2014 13:43:55 +0800 Subject: [PATCH] add performance header to control options for performance. 2.0.50 --- trunk/configure | 2 +- trunk/src/app/srs_app_recv_thread.cpp | 9 ++++ trunk/src/app/srs_app_recv_thread.hpp | 8 ++- trunk/src/core/srs_core.hpp | 2 +- trunk/src/core/srs_core_performance.cpp | 25 +++++++++ trunk/src/core/srs_core_performance.hpp | 71 +++++++++++++++++++++++++ trunk/src/rtmp/srs_protocol_buffer.cpp | 11 ++++ trunk/src/rtmp/srs_protocol_buffer.hpp | 29 ++++++---- trunk/src/rtmp/srs_protocol_rtmp.cpp | 2 + trunk/src/rtmp/srs_protocol_rtmp.hpp | 3 ++ trunk/src/rtmp/srs_protocol_stack.cpp | 2 + trunk/src/rtmp/srs_protocol_stack.hpp | 3 ++ trunk/src/srs/srs.upp | 2 + trunk/src/utest/srs_utest_kernel.cpp | 19 ++++--- trunk/src/utest/srs_utest_protocol.hpp | 4 +- 15 files changed, 167 insertions(+), 25 deletions(-) create mode 100644 trunk/src/core/srs_core_performance.cpp create mode 100644 trunk/src/core/srs_core_performance.hpp diff --git a/trunk/configure b/trunk/configure index 4b041e8a2..dd6d5f4e3 100755 --- a/trunk/configure +++ b/trunk/configure @@ -355,7 +355,7 @@ if [ $SRS_MIPS_UBUNTU12 = YES ]; then SrsLinkOptions="${SrsLinkOptions} -lgcc_eh MODULE_ID="CORE" MODULE_DEPENDS=() ModuleLibIncs=(${SRS_OBJS_DIR}) -MODULE_FILES=("srs_core" "srs_core_autofree") +MODULE_FILES=("srs_core" "srs_core_autofree" "srs_core_performance") CORE_INCS="src/core"; MODULE_DIR=${CORE_INCS} . auto/modules.sh CORE_OBJS="${MODULE_OBJS[@]}" # diff --git a/trunk/src/app/srs_app_recv_thread.cpp b/trunk/src/app/srs_app_recv_thread.cpp index 30939194b..c296e2434 100644 --- a/trunk/src/app/srs_app_recv_thread.cpp +++ b/trunk/src/app/srs_app_recv_thread.cpp @@ -28,6 +28,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #include #include +#include // when we read from socket less than this value, // sleep a while to merge read. @@ -299,6 +300,7 @@ void SrsPublishRecvThread::on_thread_start() // we donot set the auto response to false, // for the main thread never send message. +#ifdef SRS_PERF_MERGED_READ // socket recv buffer, system will double it. int nb_rbuf = SRS_MR_SOCKET_BUFFER / 2; socklen_t sock_buf_size = sizeof(int); @@ -312,6 +314,7 @@ void SrsPublishRecvThread::on_thread_start() // enable the merge read // @see https://github.com/winlinvip/simple-rtmp-server/issues/241 rtmp->set_merge_read(true, nb_rbuf, this); +#endif } void SrsPublishRecvThread::on_thread_stop() @@ -323,9 +326,11 @@ void SrsPublishRecvThread::on_thread_stop() // @see https://github.com/winlinvip/simple-rtmp-server/issues/244 st_cond_signal(error); +#ifdef SRS_PERF_MERGED_READ // disable the merge read // @see https://github.com/winlinvip/simple-rtmp-server/issues/241 rtmp->set_merge_read(false, 0, NULL); +#endif } bool SrsPublishRecvThread::can_handle() @@ -359,6 +364,7 @@ void SrsPublishRecvThread::on_recv_error(int ret) st_cond_signal(error); } +#ifdef SRS_PERF_MERGED_READ void SrsPublishRecvThread::on_read(ssize_t nread) { if (nread < 0 || mr_sleep_ms <= 0) { @@ -378,6 +384,8 @@ void SrsPublishRecvThread::on_read(ssize_t nread) void SrsPublishRecvThread::on_buffer_change(int nb_buffer) { + srs_assert(nb_buffer > 0); + // set percent. mr_small_bytes = (int)(nb_buffer / SRS_MR_SMALL_PERCENT); // select the smaller @@ -399,3 +407,4 @@ void SrsPublishRecvThread::on_buffer_change(int nb_buffer) srs_trace("merged read, buffer=%d, small=%d, sleep=%d", nb_buffer, mr_small_bytes, mr_sleep_ms); } +#endif diff --git a/trunk/src/app/srs_app_recv_thread.hpp b/trunk/src/app/srs_app_recv_thread.hpp index 7b947562c..cdaf0c1d5 100644 --- a/trunk/src/app/srs_app_recv_thread.hpp +++ b/trunk/src/app/srs_app_recv_thread.hpp @@ -34,6 +34,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #include +#include class SrsRtmpServer; class SrsMessage; @@ -133,7 +134,10 @@ public: * the publish recv thread got message and callback the source method to process message. * @see: https://github.com/winlinvip/simple-rtmp-server/issues/237 */ -class SrsPublishRecvThread : virtual public ISrsMessageHandler, virtual public IMergeReadHandler +class SrsPublishRecvThread : virtual public ISrsMessageHandler +#ifdef SRS_PERF_MERGED_READ + , virtual public IMergeReadHandler +#endif { private: SrsRecvThread trd; @@ -178,8 +182,10 @@ public: virtual void on_recv_error(int ret); // interface IMergeReadHandler public: +#ifdef SRS_PERF_MERGED_READ virtual void on_read(ssize_t nread); virtual void on_buffer_change(int nb_buffer); +#endif }; #endif diff --git a/trunk/src/core/srs_core.hpp b/trunk/src/core/srs_core.hpp index 2bc63f30e..0a67aa8f9 100644 --- a/trunk/src/core/srs_core.hpp +++ b/trunk/src/core/srs_core.hpp @@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // current release version #define VERSION_MAJOR 2 #define VERSION_MINOR 0 -#define VERSION_REVISION 49 +#define VERSION_REVISION 50 // server info. #define RTMP_SIG_SRS_KEY "SRS" #define RTMP_SIG_SRS_ROLE "origin/edge server" diff --git a/trunk/src/core/srs_core_performance.cpp b/trunk/src/core/srs_core_performance.cpp new file mode 100644 index 000000000..5da7069da --- /dev/null +++ b/trunk/src/core/srs_core_performance.cpp @@ -0,0 +1,25 @@ +/* +The MIT License (MIT) + +Copyright (c) 2013-2014 winlin + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include + diff --git a/trunk/src/core/srs_core_performance.hpp b/trunk/src/core/srs_core_performance.hpp new file mode 100644 index 000000000..ef207c3d5 --- /dev/null +++ b/trunk/src/core/srs_core_performance.hpp @@ -0,0 +1,71 @@ +/* +The MIT License (MIT) + +Copyright (c) 2013-2014 winlin + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef SRS_CORE_PERFORMANCE_HPP +#define SRS_CORE_PERFORMANCE_HPP + +/* +#include +*/ + +#include + +/** +* this file defines the perfromance options. +*/ + +/** +* to improve read performance, merge some packets then read, +* when it on and read small bytes, we sleep to wait more data., +* that is, we merge some data to read together. +* @see https://github.com/winlinvip/simple-rtmp-server/issues/241 +* @remark other macros: +* SOCKET_MAX_BUF, the max size of user-space buffer. +* SOCKET_READ_SIZE, the user space buffer for socket. +* SRS_MR_MAX_BITRATE_KBPS, the kbps of stream for system to guess the sleep time. +* SRS_MR_AVERAGE_BITRATE_KBPS, the average kbps of system. +* SRS_MR_MIN_BITRATE_KBPS, the min kbps of system. +* SRS_MR_MAX_SLEEP_MS, the max sleep time, the latency+ when sleep+. +* SRS_MR_SMALL_BYTES, sleep when got small bytes, the latency+ when small+. +* SRS_MR_SMALL_PERCENT, to calc the small bytes = SRS_MR_SOCKET_BUFFER/percent. +* SRS_MR_SOCKET_BUFFER, the socket buffer to set fd. +* @remark the actual socket buffer used to set the buffer user-space size. +* buffer = min(SOCKET_MAX_BUF, SRS_MR_SOCKET_BUFFER, SOCKET_READ_SIZE) +* small bytes = max(buffer/SRS_MR_SMALL_PERCENT, SRS_MR_SMALL_BYTES) +* sleep = calc the sleep by kbps and buffer. +* @remark the main merged-read algorithm: +* while true: +* nread = read from socket. +* sleep if nread < small bytes +* process bytes. +* @example, for the default settings, this algorithm will use: +* socket buffer set to 64KB, +* user space buffer set to 64KB, +* buffer=65536B, small=4096B, sleep=780ms +* that is, when got nread bytes smaller than 4KB, sleep(780ms). +*/ +#define SRS_PERF_MERGED_READ +#undef SRS_PERF_MERGED_READ + +#endif + diff --git a/trunk/src/rtmp/srs_protocol_buffer.cpp b/trunk/src/rtmp/srs_protocol_buffer.cpp index 12cc48b30..a54428fd7 100644 --- a/trunk/src/rtmp/srs_protocol_buffer.cpp +++ b/trunk/src/rtmp/srs_protocol_buffer.cpp @@ -26,6 +26,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #include #include +#include // the max header size, // @see SrsProtocol::read_message_header(). @@ -72,6 +73,7 @@ void SrsSimpleBuffer::append(const char* bytes, int size) data.insert(data.end(), bytes, bytes + size); } +#ifdef SRS_PERF_MERGED_READ IMergeReadHandler::IMergeReadHandler() { } @@ -79,11 +81,14 @@ IMergeReadHandler::IMergeReadHandler() IMergeReadHandler::~IMergeReadHandler() { } +#endif SrsFastBuffer::SrsFastBuffer() { +#ifdef SRS_PERF_MERGED_READ merged_read = false; _handler = NULL; +#endif p = end = buffer = NULL; nb_buffer = 0; @@ -160,6 +165,7 @@ int SrsFastBuffer::grow(ISrsBufferReader* reader, int required_size) return ret; } +#ifdef SRS_PERF_MERGED_READ /** * to improve read performance, merge some packets then read, * when it on and read small bytes, we sleep to wait more data., @@ -169,6 +175,7 @@ int SrsFastBuffer::grow(ISrsBufferReader* reader, int required_size) if (merged_read && _handler) { _handler->on_read(nread); } +#endif // we just move the ptr to next. srs_assert((int)nread > 0); @@ -178,6 +185,7 @@ int SrsFastBuffer::grow(ISrsBufferReader* reader, int required_size) return ret; } +#ifdef SRS_PERF_MERGED_READ void SrsFastBuffer::set_merge_read(bool v, int max_buffer, IMergeReadHandler* handler) { merged_read = v; @@ -194,6 +202,7 @@ void SrsFastBuffer::set_merge_read(bool v, int max_buffer, IMergeReadHandler* ha _handler->on_buffer_change(nb_buffer); } } +#endif void SrsFastBuffer::on_chunk_size(int32_t chunk_size) { @@ -208,9 +217,11 @@ void SrsFastBuffer::on_chunk_size(int32_t chunk_size) reset_buffer(buffer_size); } +#ifdef SRS_PERF_MERGED_READ if (_handler) { _handler->on_buffer_change(nb_buffer); } +#endif } int SrsFastBuffer::buffer_size() diff --git a/trunk/src/rtmp/srs_protocol_buffer.hpp b/trunk/src/rtmp/srs_protocol_buffer.hpp index 6cae2915a..396aa04ee 100644 --- a/trunk/src/rtmp/srs_protocol_buffer.hpp +++ b/trunk/src/rtmp/srs_protocol_buffer.hpp @@ -33,6 +33,17 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #include +#include + +// 4KB=4096 +// 8KB=8192 +// 16KB=16384 +// 32KB=32768 +// 64KB=65536 +// @see https://github.com/winlinvip/simple-rtmp-server/issues/241 +#define SOCKET_READ_SIZE 65536 +// the max buffer for user space socket buffer. +#define SOCKET_MAX_BUF SOCKET_READ_SIZE /** * the simple buffer use vector to append bytes, @@ -71,16 +82,7 @@ public: virtual void append(const char* bytes, int size); }; -// 4KB=4096 -// 8KB=8192 -// 16KB=16384 -// 32KB=32768 -// 64KB=65536 -// @see https://github.com/winlinvip/simple-rtmp-server/issues/241 -#define SOCKET_READ_SIZE 65536 -// the max buffer for user space socket buffer. -#define SOCKET_MAX_BUF SOCKET_READ_SIZE - +#ifdef SRS_PERF_MERGED_READ /** * to improve read performance, merge some packets then read, * when it on and read small bytes, we sleep to wait more data., @@ -105,17 +107,21 @@ public: */ virtual void on_buffer_change(int nb_buffer) = 0; }; +#endif /** * the buffer provices bytes cache for protocol. generally, * protocol recv data from socket, put into buffer, decode to RTMP message. */ +// TODO: FIXME: add utest for it. class SrsFastBuffer { private: +#ifdef SRS_PERF_MERGED_READ // the merged handler bool merged_read; IMergeReadHandler* _handler; +#endif // the user-space buffer to fill by reader, // which use fast index and reset when chunk body read ok. // @see https://github.com/winlinvip/simple-rtmp-server/issues/248 @@ -160,6 +166,7 @@ public: */ virtual int grow(ISrsBufferReader* reader, int required_size); public: +#ifdef SRS_PERF_MERGED_READ /** * to improve read performance, merge some packets then read, * when it on and read small bytes, we sleep to wait more data., @@ -170,6 +177,8 @@ public: * @see https://github.com/winlinvip/simple-rtmp-server/issues/241 */ virtual void set_merge_read(bool v, int max_buffer, IMergeReadHandler* handler); +#endif +public: /** * when chunk size changed, the buffer should change the buffer also. * to keep the socket buffer size always greater than chunk size. diff --git a/trunk/src/rtmp/srs_protocol_rtmp.cpp b/trunk/src/rtmp/srs_protocol_rtmp.cpp index c6ccc1dee..2c098a6d2 100644 --- a/trunk/src/rtmp/srs_protocol_rtmp.cpp +++ b/trunk/src/rtmp/srs_protocol_rtmp.cpp @@ -745,10 +745,12 @@ void SrsRtmpServer::set_auto_response(bool v) protocol->set_auto_response(v); } +#ifdef SRS_PERF_MERGED_READ void SrsRtmpServer::set_merge_read(bool v, int max_buffer, IMergeReadHandler* handler) { protocol->set_merge_read(v, max_buffer, handler); } +#endif void SrsRtmpServer::set_recv_timeout(int64_t timeout_us) { diff --git a/trunk/src/rtmp/srs_protocol_rtmp.hpp b/trunk/src/rtmp/srs_protocol_rtmp.hpp index de2e4c47e..cab5b3065 100644 --- a/trunk/src/rtmp/srs_protocol_rtmp.hpp +++ b/trunk/src/rtmp/srs_protocol_rtmp.hpp @@ -33,6 +33,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #include +#include class SrsProtocol; class ISrsProtocolReaderWriter; @@ -343,6 +344,7 @@ public: * @see: https://github.com/winlinvip/simple-rtmp-server/issues/217 */ virtual void set_auto_response(bool v); +#ifdef SRS_PERF_MERGED_READ /** * to improve read performance, merge some packets then read, * when it on and read small bytes, we sleep to wait more data., @@ -353,6 +355,7 @@ public: * @see https://github.com/winlinvip/simple-rtmp-server/issues/241 */ virtual void set_merge_read(bool v, int max_buffer, IMergeReadHandler* handler); +#endif /** * set/get the recv timeout in us. * if timeout, recv/send message return ERROR_SOCKET_TIMEOUT. diff --git a/trunk/src/rtmp/srs_protocol_stack.cpp b/trunk/src/rtmp/srs_protocol_stack.cpp index 609753992..23fdfee92 100644 --- a/trunk/src/rtmp/srs_protocol_stack.cpp +++ b/trunk/src/rtmp/srs_protocol_stack.cpp @@ -479,10 +479,12 @@ int SrsProtocol::manual_response_flush() return ret; } +#ifdef SRS_PERF_MERGED_READ void SrsProtocol::set_merge_read(bool v, int max_buffer, IMergeReadHandler* handler) { in_buffer->set_merge_read(v, max_buffer, handler); } +#endif void SrsProtocol::set_recv_timeout(int64_t timeout_us) { diff --git a/trunk/src/rtmp/srs_protocol_stack.hpp b/trunk/src/rtmp/srs_protocol_stack.hpp index 18531224f..49f332b00 100644 --- a/trunk/src/rtmp/srs_protocol_stack.hpp +++ b/trunk/src/rtmp/srs_protocol_stack.hpp @@ -42,6 +42,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #include #include +#include class ISrsProtocolReaderWriter; class SrsFastBuffer; @@ -271,6 +272,7 @@ public: */ virtual int manual_response_flush(); public: +#ifdef SRS_PERF_MERGED_READ /** * to improve read performance, merge some packets then read, * when it on and read small bytes, we sleep to wait more data., @@ -281,6 +283,7 @@ public: * @see https://github.com/winlinvip/simple-rtmp-server/issues/241 */ virtual void set_merge_read(bool v, int max_buffer, IMergeReadHandler* handler); +#endif public: /** * set/get the recv timeout in us. diff --git a/trunk/src/srs/srs.upp b/trunk/src/srs/srs.upp index 3e0b8a62a..c400d51a7 100755 --- a/trunk/src/srs/srs.upp +++ b/trunk/src/srs/srs.upp @@ -15,6 +15,8 @@ file ..\core\srs_core.cpp, ..\core\srs_core_autofree.hpp, ..\core\srs_core_autofree.cpp, + ..\core\srs_core_performance.hpp, + ..\core\srs_core_performance.cpp, kernel readonly separator, ..\kernel\srs_kernel_codec.hpp, ..\kernel\srs_kernel_codec.cpp, diff --git a/trunk/src/utest/srs_utest_kernel.cpp b/trunk/src/utest/srs_utest_kernel.cpp index 5c5e968d2..45bcbdcd0 100644 --- a/trunk/src/utest/srs_utest_kernel.cpp +++ b/trunk/src/utest/srs_utest_kernel.cpp @@ -203,7 +203,7 @@ int MockBufferReader::read(void* buf, size_t size, ssize_t* nread) VOID TEST(KernelBufferTest, DefaultObject) { - SrsFastBuffer b; + SrsSimpleBuffer b; EXPECT_EQ(0, b.length()); EXPECT_EQ(NULL, b.bytes()); @@ -211,7 +211,7 @@ VOID TEST(KernelBufferTest, DefaultObject) VOID TEST(KernelBufferTest, AppendBytes) { - SrsFastBuffer b; + SrsSimpleBuffer b; char winlin[] = "winlin"; b.append(winlin, strlen(winlin)); @@ -231,7 +231,7 @@ VOID TEST(KernelBufferTest, AppendBytes) VOID TEST(KernelBufferTest, EraseBytes) { - SrsFastBuffer b; + SrsSimpleBuffer b; b.erase(0); b.erase(-1); @@ -265,22 +265,21 @@ VOID TEST(KernelBufferTest, EraseBytes) EXPECT_EQ(0, b.length()); } -VOID TEST(KernelBufferTest, Grow) +VOID TEST(KernelFastBufferTest, Grow) { SrsFastBuffer b; MockBufferReader r("winlin"); b.grow(&r, 1); - EXPECT_EQ(6, b.length()); - EXPECT_EQ('w', b.bytes()[0]); + EXPECT_EQ('w', b.read_1byte()); b.grow(&r, 3); - EXPECT_EQ(6, b.length()); - EXPECT_EQ('n', b.bytes()[2]); + b.skip(1); + EXPECT_EQ('n', b.read_1byte()); b.grow(&r, 100); - EXPECT_EQ(102, b.length()); - EXPECT_EQ('l', b.bytes()[99]); + b.skip(99); + EXPECT_EQ('w', b.read_1byte()); } /** diff --git a/trunk/src/utest/srs_utest_protocol.hpp b/trunk/src/utest/srs_utest_protocol.hpp index 060f5a54e..351975987 100644 --- a/trunk/src/utest/srs_utest_protocol.hpp +++ b/trunk/src/utest/srs_utest_protocol.hpp @@ -78,9 +78,9 @@ public: int64_t recv_bytes; int64_t send_bytes; // data source for socket read. - SrsFastBuffer in_buffer; + SrsSimpleBuffer in_buffer; // data buffer for socket send. - SrsFastBuffer out_buffer; + SrsSimpleBuffer out_buffer; public: MockBufferIO(); virtual ~MockBufferIO();