Use flat_map in RTCPReceiver

RTCPReceiver initially used a std::map, which made
RTCPReceiver::IncomingPacket's use of std::map represent ~0.45% CPU in
highly loaded media servers. Using std::unordered_map in change 216321
reduced it only slightly, to 0.39%.

This is the second attempt to reduce it even further. By using a
flat_map and taking advantage of the increased cache locality, the hope
is that it will be reduced. These maps generally have low cardinality
(indexed by SSRC), and are looked up often, but modified less often,
which make them a potential candidate for flat_map.

Bug: webrtc:12689
Change-Id: I6733ccf3484d1c54e661250fb6712971b80fa2a9
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/225203
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Reviewed-by: Danil Chapovalov <danilchap@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#34432}
This commit is contained in:
Victor Boivie
2021-07-06 23:14:51 +02:00
committed by WebRTC LUCI CQ
parent 5900ba0ee8
commit f715618eee
3 changed files with 10 additions and 20 deletions

View File

@ -296,6 +296,7 @@ rtc_library("rtp_rtcp") {
"../../rtc_base:rtc_base_approved", "../../rtc_base:rtc_base_approved",
"../../rtc_base:rtc_numerics", "../../rtc_base:rtc_numerics",
"../../rtc_base:safe_minmax", "../../rtc_base:safe_minmax",
"../../rtc_base/containers:flat_map",
"../../rtc_base/experiments:field_trial_parser", "../../rtc_base/experiments:field_trial_parser",
"../../rtc_base/synchronization:mutex", "../../rtc_base/synchronization:mutex",
"../../rtc_base/system:no_unique_address", "../../rtc_base/system:no_unique_address",

View File

@ -809,14 +809,9 @@ void RTCPReceiver::HandleBye(const CommonHeader& rtcp_block) {
// Clear our lists. // Clear our lists.
rtts_.erase(bye.sender_ssrc()); rtts_.erase(bye.sender_ssrc());
for (auto it = received_report_blocks_.begin(); EraseIf(received_report_blocks_, [&](const auto& elem) {
it != received_report_blocks_.end();) { return elem.second.report_block().sender_ssrc == bye.sender_ssrc();
if (it->second.report_block().sender_ssrc == bye.sender_ssrc()) { });
received_report_blocks_.erase(it++);
} else {
++it;
}
}
TmmbrInformation* tmmbr_info = GetTmmbrInformation(bye.sender_ssrc()); TmmbrInformation* tmmbr_info = GetTmmbrInformation(bye.sender_ssrc());
if (tmmbr_info) if (tmmbr_info)

View File

@ -13,9 +13,7 @@
#include <list> #include <list>
#include <map> #include <map>
#include <set>
#include <string> #include <string>
#include <unordered_map>
#include <vector> #include <vector>
#include "api/array_view.h" #include "api/array_view.h"
@ -27,6 +25,7 @@
#include "modules/rtp_rtcp/source/rtcp_packet/dlrr.h" #include "modules/rtp_rtcp/source/rtcp_packet/dlrr.h"
#include "modules/rtp_rtcp/source/rtcp_packet/tmmb_item.h" #include "modules/rtp_rtcp/source/rtcp_packet/tmmb_item.h"
#include "modules/rtp_rtcp/source/rtp_rtcp_interface.h" #include "modules/rtp_rtcp/source/rtp_rtcp_interface.h"
#include "rtc_base/containers/flat_map.h"
#include "rtc_base/synchronization/mutex.h" #include "rtc_base/synchronization/mutex.h"
#include "rtc_base/system/no_unique_address.h" #include "rtc_base/system/no_unique_address.h"
#include "rtc_base/thread_annotations.h" #include "rtc_base/thread_annotations.h"
@ -368,7 +367,7 @@ class RTCPReceiver final {
std::list<RrtrInformation> received_rrtrs_ std::list<RrtrInformation> received_rrtrs_
RTC_GUARDED_BY(rtcp_receiver_lock_); RTC_GUARDED_BY(rtcp_receiver_lock_);
// Received RRTR information mapped by remote ssrc. // Received RRTR information mapped by remote ssrc.
std::unordered_map<uint32_t, std::list<RrtrInformation>::iterator> flat_map<uint32_t, std::list<RrtrInformation>::iterator>
received_rrtrs_ssrc_it_ RTC_GUARDED_BY(rtcp_receiver_lock_); received_rrtrs_ssrc_it_ RTC_GUARDED_BY(rtcp_receiver_lock_);
// Estimated rtt, zero when there is no valid estimate. // Estimated rtt, zero when there is no valid estimate.
@ -377,21 +376,16 @@ class RTCPReceiver final {
int64_t oldest_tmmbr_info_ms_ RTC_GUARDED_BY(rtcp_receiver_lock_); int64_t oldest_tmmbr_info_ms_ RTC_GUARDED_BY(rtcp_receiver_lock_);
// Mapped by remote ssrc. // Mapped by remote ssrc.
std::unordered_map<uint32_t, TmmbrInformation> tmmbr_infos_ flat_map<uint32_t, TmmbrInformation> tmmbr_infos_
RTC_GUARDED_BY(rtcp_receiver_lock_); RTC_GUARDED_BY(rtcp_receiver_lock_);
// Round-Trip Time per remote sender ssrc. // Round-Trip Time per remote sender ssrc.
std::unordered_map<uint32_t, RttStats> rtts_ flat_map<uint32_t, RttStats> rtts_ RTC_GUARDED_BY(rtcp_receiver_lock_);
RTC_GUARDED_BY(rtcp_receiver_lock_);
// TODO(boivie): `received_report_blocks_` should be converted
// to std::unordered_map, but as there are too many tests that assume a
// specific order, it's not easily done.
// Report blocks per local source ssrc. // Report blocks per local source ssrc.
std::map<uint32_t, ReportBlockData> received_report_blocks_ flat_map<uint32_t, ReportBlockData> received_report_blocks_
RTC_GUARDED_BY(rtcp_receiver_lock_); RTC_GUARDED_BY(rtcp_receiver_lock_);
std::unordered_map<uint32_t, LastFirStatus> last_fir_ flat_map<uint32_t, LastFirStatus> last_fir_
RTC_GUARDED_BY(rtcp_receiver_lock_); RTC_GUARDED_BY(rtcp_receiver_lock_);
// The last time we received an RTCP Report block for this module. // The last time we received an RTCP Report block for this module.