Closed
Bug 822129
Opened 12 years ago
Closed 9 years ago
Reduce memcpys in MediaPipeline
Categories
(Core :: WebRTC: Networking, defect, P4)
Tracking
()
RESOLVED
FIXED
mozilla35
Tracking | Status | |
---|---|---|
firefox41 | --- | fixed |
backlog | webrtc/webaudio+ |
People
(Reporter: ekr, Assigned: jesup)
Details
(Whiteboard: [WebRTC], )
Attachments
(1 file, 5 obsolete files)
10.24 KB,
patch
|
bwc
:
review+
|
Details | Diff | Splinter Review |
Every packet out requires a number of copies for thread transitions and to accomodate SRTP overhead. See if we can do something to reduce this.
Updated•12 years ago
|
Priority: -- → P3
Whiteboard: [WebRTC], [blocking-webrtc-]
Assignee | ||
Comment 1•11 years ago
|
||
Assignee | ||
Updated•11 years ago
|
Attachment #739934 -
Flags: review?(ekr)
Reporter | ||
Comment 2•11 years ago
|
||
What does profiling show is the impact of this change?
Assignee | ||
Comment 3•11 years ago
|
||
This is tricky on a fast machine, and will vary according to allocator, memory pressure, fragmentation level, etc. Some comparative profiles show without this, malloc/free from SendRtpPacket_s() is around 0.5% of STS thread time. With the patch, it never got hit at all by the profiler. So it's a small win (maybe 0.1% overall, as STS thread is on the perf radar, but not the hottest thread), and might be larger on B2G/Android or perhaps on Windows. It removes hundreds of allocations-per-second (50+ for audio, 30-200+ for video), per A/V stream. And it's easy.
Reporter | ||
Comment 4•11 years ago
|
||
Comment on attachment 739934 [details] [diff] [review] don't alloc/free on every packet send in MediaPipeline Review of attachment 739934 [details] [diff] [review]: ----------------------------------------------------------------- MediaPipeline::SendRtpPacket() and MediaPipeline::SendRtcpPacket() both already allocate DataBuffers to allow for an async thread dispatch. nsresult MediaPipeline::PipelineTransport::SendRtpPacket( const void *data, int len) { nsAutoPtr<DataBuffer> buf(new DataBuffer(static_cast<const uint8_t *>(data), len)); RUN_ON_THREAD(sts_thread_, WrapRunnable( RefPtr<MediaPipeline::PipelineTransport>(this), &MediaPipeline::PipelineTransport::SendRtpPacket_s, buf), NS_DISPATCH_NORMAL); return NS_OK; } Instead of having a new member variable that we use to store the temp buffer, we should just extend DataBuffer to have separate length and size values (where size >= length). Then we can allocate an oversized DataBuffer and pass it down, skipping all the memory fussing around in SendRtpPacket_s(). ::: media/webrtc/signaling/src/mediapipeline/MediaPipeline.h @@ +157,5 @@ > > + // SRTP needs larger buffers for Auth tags > + // Avoid reallocating SRTP packet buffer on every send > + int packet_size_; > + nsAutoPtr<unsigned char> packet_; nsAutoPtr uses delete but because we allocated an array we need delete[] This should be a ScopedDeleteArray, which does the right thing and also has stronger ownership semantics.
Attachment #739934 -
Flags: review?(ekr) → review-
Assignee | ||
Comment 5•11 years ago
|
||
updated to expand the DataBuffer class to support grow-in-place for SRTP
Assignee | ||
Updated•11 years ago
|
Attachment #739934 -
Attachment is obsolete: true
Assignee | ||
Updated•11 years ago
|
Attachment #751220 -
Flags: review?(ekr)
Assignee | ||
Updated•11 years ago
|
Assignee: nobody → rjesup
Reporter | ||
Comment 6•11 years ago
|
||
Comment on attachment 751220 [details] [diff] [review] don't alloc/free on every packet send in MediaPipeline Review of attachment 751220 [details] [diff] [review]: ----------------------------------------------------------------- Seems like the DataBuffer aPI should be safer. ::: media/mtransport/databuffer.h @@ +26,4 @@ > } > > + void Assign(const uint8_t *data, size_t len, size_t size) { > + data_ = new unsigned char[ size ? size : 1]; // Don't depend on new [0]. This code should guarantee that size >= len @@ +42,5 @@ > + size_ = size; > + } > + } > + > + void SetLength(size_t len) { This should be a run-time check as well as an assert. ::: media/webrtc/signaling/src/mediapipeline/MediaPipeline.cpp @@ +563,5 @@ > MOZ_ASSERT(pipeline_->rtp_transport_); > NS_ENSURE_TRUE(pipeline_->rtp_transport_, NS_ERROR_NULL_POINTER); > > + // libsrtp enciphers in place, so we need a big enough buffer. > + data->EnsureCapacity(data->len() + SRTP_MAX_EXPANSION); Do we actually want to call this here? The buffer should always be big enough and the ProtectRtp call will fail if it's not. ::: media/webrtc/signaling/src/mediapipeline/MediaPipeline.h @@ +135,5 @@ > public: > // Implement the TransportInterface functions > PipelineTransport(MediaPipeline *pipeline) > : pipeline_(pipeline), > + sts_thread_(pipeline->sts_thread_) {} What changed here?
Attachment #751220 -
Flags: review?(ekr) → review-
Assignee | ||
Comment 7•11 years ago
|
||
Assignee | ||
Updated•11 years ago
|
Attachment #751220 -
Attachment is obsolete: true
Assignee | ||
Comment 8•11 years ago
|
||
Comment on attachment 751577 [details] [diff] [review] don't alloc/free on every packet send in MediaPipeline The change to MediaPipeline.h was a tab -> spaces
Attachment #751577 -
Flags: review?(ekr)
Assignee | ||
Comment 9•11 years ago
|
||
replace magic constant '20' with correct value (will verify with ASAN)
Assignee | ||
Updated•11 years ago
|
Attachment #751577 -
Attachment is obsolete: true
Attachment #751577 -
Flags: review?(ekr)
Assignee | ||
Updated•11 years ago
|
Attachment #754836 -
Flags: review?(ekr)
Updated•10 years ago
|
Target Milestone: --- → mozilla33
Updated•10 years ago
|
Whiteboard: [WebRTC], [blocking-webrtc-] → [WebRTC], [blocking-webrtc-], p=1
Updated•10 years ago
|
Target Milestone: mozilla33 → mozilla35
Reporter | ||
Comment 10•10 years ago
|
||
Comment on attachment 754836 [details] [diff] [review] don't alloc/free on every packet send in MediaPipeline Review of attachment 754836 [details] [diff] [review]: ----------------------------------------------------------------- This patch has bit-rotted because databuffer.h has changed. Given the number of copies in the current code, I would be surprised if this were a major contributor to CPU consumption, but if you feel like unbitrotting it and resubmitting, I will TAL.
Attachment #754836 -
Flags: review?(ekr)
Assignee | ||
Comment 11•10 years ago
|
||
Unbitrotted. Green Try: https://tbpl.mozilla.org/?tree=Try&rev=4beb0f7be284 (with some ASAN retriggers just for good measure)
Assignee | ||
Updated•10 years ago
|
Attachment #754836 -
Attachment is obsolete: true
Comment 12•9 years ago
|
||
Comment on attachment 8485909 [details] [diff] [review] don't alloc/free on every packet send in MediaPipeline Review of attachment 8485909 [details] [diff] [review]: ----------------------------------------------------------------- I think that we should land this change. After rebasing, that is. ::: media/mtransport/databuffer.h @@ +35,4 @@ > len_ = len; > } > > + void Allocate(size_t size) { This should just call SetLength(0); EnsureCapacity(size); ::: media/webrtc/signaling/src/mediapipeline/MediaPipeline.cpp @@ +863,5 @@ > MOZ_ASSERT(pipeline_->rtp_.transport_); > NS_ENSURE_TRUE(pipeline_->rtp_.transport_, NS_ERROR_NULL_POINTER); > > + // libsrtp enciphers in place, so we need a big enough buffer. > + // Ensured by our only caller This should assert that the size is genuinely large enough. MOZ_ASSERT is verifiable; comments aren't. @@ +874,3 @@ > return res; > + } > + // don't need to SetLength() since we'll just delete this Change to: // Don't call data->SetLength(out_len), since we don't use the value.
Attachment #8485909 -
Flags: feedback+
Comment 13•9 years ago
|
||
Randell -- Can you clean this up and get it reviewed & landed?
backlog: --- → webRTC+
Rank: 45
Flags: needinfo?(rjesup)
Priority: P3 → P4
Whiteboard: [WebRTC], [blocking-webrtc-], p=1 → [WebRTC],
Assignee | ||
Comment 14•9 years ago
|
||
unbitrotted, and cleaned up to remove the heavily-duplicated code pattern for RTP and RTCP
Attachment #8615988 -
Flags: review?(docfaraday)
Assignee | ||
Updated•9 years ago
|
Attachment #8485909 -
Attachment is obsolete: true
Comment 15•9 years ago
|
||
Comment on attachment 8615988 [details] [diff] [review] don't alloc/free on every packet send in MediaPipeline Review of attachment 8615988 [details] [diff] [review]: ----------------------------------------------------------------- Some small stuff, no need for another cycle. ::: media/mtransport/databuffer.h @@ +16,5 @@ > namespace mozilla { > > class DataBuffer { > public: > + DataBuffer() : data_(nullptr), len_(0), size_(0) {} Suggest 'capacity' instead of 'size'. @@ +48,5 @@ > + size_ = size; > + } > + } > + > + void SetLength(size_t len) { Does anything use this? Also, should we allow this to increase len_? ::: media/webrtc/signaling/src/mediapipeline/MediaPipeline.h @@ +191,5 @@ > virtual nsresult SendRtcpPacket(const void* data, int len); > > private: > + virtual nsresult SendRtpRtcpPacket_s(nsAutoPtr<DataBuffer> data, > + bool is_rtp); Not that you did this, but why is this virtual anyhow? ::: media/webrtc/signaling/src/mediapipeline/SrtpFlow.h @@ +21,5 @@ > #define SRTP_MASTER_KEY_LENGTH 16 > #define SRTP_MASTER_SALT_LENGTH 14 > #define SRTP_TOTAL_KEY_LENGTH (SRTP_MASTER_KEY_LENGTH + SRTP_MASTER_SALT_LENGTH) > > +// SRTCP requires an auth tag *plus* a 4-byte index-plus-'E'-bit value (see RFC 3711) Wrap to 80
Attachment #8615988 -
Flags: review?(docfaraday) → review+
I had to back this out in https://hg.mozilla.org/integration/mozilla-inbound/rev/564799379b68 for cpp unittest orange: https://treeherder.mozilla.org/logviewer.html#?job_id=10495588&repo=mozilla-inbound
Assignee | ||
Comment 19•9 years ago
|
||
It was a minor issue with the transport_unittests relying on a side-effect that wasn't preserved (in an API that's not used in non-unittest code). Relanded
Flags: needinfo?(rjesup)
You need to log in
before you can comment on or make changes to this bug.
Description
•