- Revision
- 224990
- Author
- [email protected]
- Date
- 2017-11-17 15:00:43 -0800 (Fri, 17 Nov 2017)
Log Message
Add a TimingScope class for microbenchmarking sections of code
https://bugs.webkit.org/show_bug.cgi?id=179825
Reviewed by Zalan Bujtas.
Add a class, similar to B3TimingScope, which makes it easy to microbenchmark
sections of code. Use looks like:
TimingScope scope("some label", 100);
where this will print mean scope duration every 100 calls. Sample output:
FETurbulence::platformApplySoftware: 100 calls, mean duration: 3.073181ms
FETurbulence::platformApplySoftware: 200 calls, mean duration: 3.074612ms
FETurbulence::platformApplySoftware: 300 calls, mean duration: 3.065722ms
Because TimingScope needs to store state beween invocations, and there may be
multiple TimingScopes in use at the same time, data is stored in a global
hash map with atomic access.
* WTF.xcodeproj/project.pbxproj:
* wtf/CMakeLists.txt:
* wtf/TimingScope.cpp: Added.
(WTF::TimingScope::scopeDidEnd):
* wtf/TimingScope.h: Added.
(WTF::TimingScope::TimingScope):
(WTF::TimingScope::~TimingScope):
Modified Paths
Added Paths
Diff
Modified: trunk/Source/WTF/ChangeLog (224989 => 224990)
--- trunk/Source/WTF/ChangeLog 2017-11-17 22:53:46 UTC (rev 224989)
+++ trunk/Source/WTF/ChangeLog 2017-11-17 23:00:43 UTC (rev 224990)
@@ -1,3 +1,33 @@
+2017-11-17 Simon Fraser <[email protected]>
+
+ Add a TimingScope class for microbenchmarking sections of code
+ https://bugs.webkit.org/show_bug.cgi?id=179825
+
+ Reviewed by Zalan Bujtas.
+
+ Add a class, similar to B3TimingScope, which makes it easy to microbenchmark
+ sections of code. Use looks like:
+
+ TimingScope scope("some label", 100);
+
+ where this will print mean scope duration every 100 calls. Sample output:
+
+ FETurbulence::platformApplySoftware: 100 calls, mean duration: 3.073181ms
+ FETurbulence::platformApplySoftware: 200 calls, mean duration: 3.074612ms
+ FETurbulence::platformApplySoftware: 300 calls, mean duration: 3.065722ms
+
+ Because TimingScope needs to store state beween invocations, and there may be
+ multiple TimingScopes in use at the same time, data is stored in a global
+ hash map with atomic access.
+
+ * WTF.xcodeproj/project.pbxproj:
+ * wtf/CMakeLists.txt:
+ * wtf/TimingScope.cpp: Added.
+ (WTF::TimingScope::scopeDidEnd):
+ * wtf/TimingScope.h: Added.
+ (WTF::TimingScope::TimingScope):
+ (WTF::TimingScope::~TimingScope):
+
2017-11-17 Alex Christensen <[email protected]>
Clean up after r224952
Modified: trunk/Source/WTF/WTF.xcodeproj/project.pbxproj (224989 => 224990)
--- trunk/Source/WTF/WTF.xcodeproj/project.pbxproj 2017-11-17 22:53:46 UTC (rev 224989)
+++ trunk/Source/WTF/WTF.xcodeproj/project.pbxproj 2017-11-17 23:00:43 UTC (rev 224990)
@@ -31,6 +31,7 @@
0F66B28E1DC97BAB004A1D3F /* Seconds.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F66B2841DC97BAB004A1D3F /* Seconds.cpp */; };
0F66B2901DC97BAB004A1D3F /* TimeWithDynamicClockType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F66B2861DC97BAB004A1D3F /* TimeWithDynamicClockType.cpp */; };
0F66B2921DC97BAB004A1D3F /* WallTime.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F66B2881DC97BAB004A1D3F /* WallTime.cpp */; };
+ 0F7075F51FBF53CD00489AF0 /* TimingScope.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F7075F41FBF537A00489AF0 /* TimingScope.cpp */; };
0F7C5FB61D885CF20044F5E2 /* FastBitVector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F7C5FB51D885CF20044F5E2 /* FastBitVector.cpp */; };
0F824A681B7443A0002E345D /* ParkingLot.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F824A641B7443A0002E345D /* ParkingLot.cpp */; };
0F8F2B92172E0103007DBDA5 /* CompilationThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F8F2B8F172E00F0007DBDA5 /* CompilationThread.cpp */; };
@@ -203,6 +204,8 @@
0F66B2871DC97BAB004A1D3F /* TimeWithDynamicClockType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TimeWithDynamicClockType.h; sourceTree = "<group>"; };
0F66B2881DC97BAB004A1D3F /* WallTime.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WallTime.cpp; sourceTree = "<group>"; };
0F66B2891DC97BAB004A1D3F /* WallTime.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WallTime.h; sourceTree = "<group>"; };
+ 0F7075F31FBF537A00489AF0 /* TimingScope.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TimingScope.h; sourceTree = "<group>"; };
+ 0F7075F41FBF537A00489AF0 /* TimingScope.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = TimingScope.cpp; sourceTree = "<group>"; };
0F725CAB1C50461600AD943A /* RangeSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RangeSet.h; sourceTree = "<group>"; };
0F79C7C31E73511800EB34D1 /* FastTLS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FastTLS.h; sourceTree = "<group>"; };
0F7C5FB51D885CF20044F5E2 /* FastBitVector.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FastBitVector.cpp; sourceTree = "<group>"; };
@@ -1016,6 +1019,8 @@
A8A4733F151A825B004123FF /* ThreadSpecific.h */,
0F66B2861DC97BAB004A1D3F /* TimeWithDynamicClockType.cpp */,
0F66B2871DC97BAB004A1D3F /* TimeWithDynamicClockType.h */,
+ 0F7075F41FBF537A00489AF0 /* TimingScope.cpp */,
+ 0F7075F31FBF537A00489AF0 /* TimingScope.h */,
553071C91C40427200384898 /* TinyLRUCache.h */,
0FED67B51B22D4D80066CE15 /* TinyPtrSet.h */,
149EF16216BBFE0D000A4331 /* TriState.h */,
@@ -1441,6 +1446,7 @@
93934BD518A1F16900D0D6A1 /* StringViewCF.cpp in Sources */,
93934BD318A1E8C300D0D6A1 /* StringViewObjC.mm in Sources */,
A8A473B7151A825B004123FF /* strtod.cc in Sources */,
+ 0F7075F51FBF53CD00489AF0 /* TimingScope.cpp in Sources */,
52183012C99E476A84EEBEA8 /* SymbolImpl.cpp in Sources */,
70A993FE1AD7151300FA615B /* SymbolRegistry.cpp in Sources */,
1C181C7F1D3078DA00F5FA16 /* TextBreakIterator.cpp in Sources */,
Modified: trunk/Source/WTF/wtf/CMakeLists.txt (224989 => 224990)
--- trunk/Source/WTF/wtf/CMakeLists.txt 2017-11-17 22:53:46 UTC (rev 224989)
+++ trunk/Source/WTF/wtf/CMakeLists.txt 2017-11-17 23:00:43 UTC (rev 224990)
@@ -145,6 +145,7 @@
Threading.h
ThreadingPrimitives.h
TimeWithDynamicClockType.h
+ TimingScope.h
TinyPtrSet.h
UUID.h
UniqueRef.h
@@ -263,6 +264,7 @@
ThreadMessage.cpp
Threading.cpp
TimeWithDynamicClockType.cpp
+ TimingScope.cpp
UUID.cpp
WallTime.cpp
WordLock.cpp
Added: trunk/Source/WTF/wtf/TimingScope.cpp (0 => 224990)
--- trunk/Source/WTF/wtf/TimingScope.cpp (rev 0)
+++ trunk/Source/WTF/wtf/TimingScope.cpp 2017-11-17 23:00:43 UTC (rev 224990)
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "TimingScope.h"
+
+#include <wtf/HashMap.h>
+#include <wtf/Lock.h>
+
+namespace WTF {
+
+namespace {
+
+class State {
+ WTF_MAKE_NONCOPYABLE(State);
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+
+ struct CallData {
+ Seconds totalDuration;
+ unsigned callCount { 0 };
+
+ Seconds meanDuration() const { return totalDuration / callCount; }
+ };
+
+ State() = default;
+
+ const CallData& addToTotal(const char* name, Seconds duration)
+ {
+ auto locker = holdLock(lock);
+ auto& result = totals.add(name, CallData()).iterator->value;
+ ++result.callCount;
+ result.totalDuration += duration;
+ return result;
+ }
+
+private:
+ HashMap<const char*, CallData> totals;
+ Lock lock;
+};
+
+State& state()
+{
+ static Atomic<State*> s_state;
+ return ensurePointer(s_state, [] { return new State(); });
+}
+
+} // anonymous namespace
+
+void TimingScope::scopeDidEnd()
+{
+ const auto& data = "" MonotonicTime::now() - m_startTime);
+ if (!(data.callCount % m_logIterationInterval))
+ WTFLogAlways("%s: %u calls, mean duration: %.6fms", m_name, data.callCount, data.meanDuration().milliseconds());
+}
+
+} // namespace WebCore
Added: trunk/Source/WTF/wtf/TimingScope.h (0 => 224990)
--- trunk/Source/WTF/wtf/TimingScope.h (rev 0)
+++ trunk/Source/WTF/wtf/TimingScope.h 2017-11-17 23:00:43 UTC (rev 224990)
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <wtf/MonotonicTime.h>
+#include <wtf/Noncopyable.h>
+
+namespace WTF {
+
+// TimingScope is intended for microbenchmarking sections of code.
+//
+// Do not leave in shipping code.
+//
+// Mean scope durations are printed using WTFLogAlways every Nth call, where N is specified by logIterationInterval.
+
+class TimingScope {
+ WTF_MAKE_NONCOPYABLE(TimingScope);
+public:
+ TimingScope(const char* name, unsigned logIterationInterval = 1)
+ : m_startTime(MonotonicTime::now())
+ , m_name(name)
+ , m_logIterationInterval(logIterationInterval)
+ {
+ }
+
+ ~TimingScope()
+ {
+ scopeDidEnd();
+ }
+
+private:
+ WTF_EXPORT_PRIVATE void scopeDidEnd();
+
+ MonotonicTime m_startTime;
+ const char* m_name;
+ unsigned m_logIterationInterval;
+};
+
+} // namespace WTF
+
+using WTF::TimingScope;
+