webrtc/system_wrappers/include/denormal_disabler.h
Alessio Bazzica 0441bb625f APM: add HW-only denormal disabler
Denormal numbers (see [1]) may origin in APM when the input is zeroed
after a non-zero signal. In extreme cases, instructions involving
denormal operands may run as much as 100 times slower, which seems to
be the case (to some extent) of crbug.com/1227566.

This CL adds a class that disables denormals only via hardware on x86
and on ARM. The class is used in APM and it is an adaption of [2].

Tested: appr.tc call on Chromium (Win, Mac)

[1] https://en.wikipedia.org/wiki/Denormal_number
[2] https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/platform/audio/denormal_disabler.h

Fixed: chromium:1227566
Change-Id: I0ed2eab55dc597529f09f93c26c7a01de051fdbe
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/227768
Reviewed-by: Magnus Flodman <mflodman@webrtc.org>
Reviewed-by: Per Åhgren <peah@webrtc.org>
Commit-Queue: Alessio Bazzica <alessiob@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#34701}
2021-08-10 15:48:22 +00:00

54 lines
1.9 KiB
C++

/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef SYSTEM_WRAPPERS_INCLUDE_DENORMAL_DISABLER_H_
#define SYSTEM_WRAPPERS_INCLUDE_DENORMAL_DISABLER_H_
#include "rtc_base/system/arch.h"
namespace webrtc {
// Activates the hardware (HW) way to flush denormals (see [1]) to zero as they
// can very seriously impact performance. At destruction time restores the
// denormals handling state read by the ctor; hence, supports nested calls.
// Equals a no-op if the architecture is not x86 or ARM or if the compiler is
// not CLANG.
// [1] https://en.wikipedia.org/wiki/Denormal_number
//
// Example usage:
//
// void Foo() {
// DenormalDisabler d;
// ...
// }
class DenormalDisabler {
public:
// Ctor. If `enabled` is true and architecture and compiler are supported,
// stores the HW settings for denormals, disables denormals and sets
// `disabling_activated_` to true. Otherwise, only sets `disabling_activated_`
// to false.
explicit DenormalDisabler(bool enabled);
DenormalDisabler(const DenormalDisabler&) = delete;
DenormalDisabler& operator=(const DenormalDisabler&) = delete;
// Dtor. If `disabling_activated_` is true, restores the denormals HW settings
// read by the ctor before denormals were disabled. Otherwise it's a no-op.
~DenormalDisabler();
// Returns true if architecture and compiler are supported.
static bool IsSupported();
private:
const int status_word_;
const bool disabling_activated_;
};
} // namespace webrtc
#endif // SYSTEM_WRAPPERS_INCLUDE_DENORMAL_DISABLER_H_