1 // Copyright 2022 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "base/cpu_reduction_experiment.h" 6 7 #include <atomic> 8 9 #include "base/check.h" 10 #include "base/dcheck_is_on.h" 11 #include "base/feature_list.h" 12 #include "base/rand_util.h" 13 14 namespace base { 15 16 namespace { 17 18 // Whether to enable a series of optimizations that reduce total CPU 19 // utilization. 20 BASE_FEATURE(kReduceCpuUtilization, 21 "ReduceCpuUtilization2", 22 FEATURE_ENABLED_BY_DEFAULT); 23 24 class CpuReductionExperimentSubSampler { 25 public: CpuReductionExperimentSubSampler()26 CpuReductionExperimentSubSampler() : counter_(base::RandUint64()) {} 27 ShouldLogHistograms()28 bool ShouldLogHistograms() { 29 // Relaxed memory order since there is no dependent memory access. 30 uint64_t val = counter_.fetch_add(1, std::memory_order_relaxed); 31 return val % 1000 == 0; 32 } 33 34 private: 35 std::atomic<uint64_t> counter_{0}; 36 }; 37 38 // Singleton instance of CpuReductionExperimentSubSampler. This is only set when 39 // the ReduceCpuUtilization experiment is enabled -- as a result, it's ok to 40 // assume that the experiment is disabled when this is not set. 41 CpuReductionExperimentSubSampler* g_subsampler = nullptr; 42 43 #if DCHECK_IS_ON() 44 // Atomic to support concurrent writes from IsRunningCpuReductionExperiment(). 45 std::atomic_bool g_accessed_subsampler = false; 46 #endif 47 48 } // namespace 49 IsRunningCpuReductionExperiment()50bool IsRunningCpuReductionExperiment() { 51 #if DCHECK_IS_ON() 52 // Relaxed memory order since there is no dependent memory access. 53 g_accessed_subsampler.store(true, std::memory_order_relaxed); 54 #endif 55 return !!g_subsampler; 56 } 57 InitializeCpuReductionExperiment()58void InitializeCpuReductionExperiment() { 59 #if DCHECK_IS_ON() 60 // TSAN should generate an error if InitializeCpuReductionExperiment() races 61 // with IsRunningCpuReductionExperiment(). 62 // 63 // Relaxed memory order since there is no dependent memory access. 64 DCHECK(!g_accessed_subsampler.load(std::memory_order_relaxed)); 65 #endif 66 if (FeatureList::IsEnabled(kReduceCpuUtilization)) { 67 g_subsampler = new CpuReductionExperimentSubSampler(); 68 } 69 } 70 ShouldLogHistogramForCpuReductionExperiment()71bool ShouldLogHistogramForCpuReductionExperiment() { 72 if (!IsRunningCpuReductionExperiment()) 73 return true; 74 return g_subsampler->ShouldLogHistograms(); 75 } 76 77 } // namespace base 78