OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Provides a minimal wrapping of the Blink image decoders. Used to perform | 5 // Provides a minimal wrapping of the Blink image decoders. Used to perform |
6 // a non-threaded, memory-to-memory image decode using micro second accuracy | 6 // a non-threaded, memory-to-memory image decode using micro second accuracy |
7 // clocks to measure image decode time. Optionally applies color correction | 7 // clocks to measure image decode time. Optionally applies color correction |
8 // during image decoding on supported platforms (default off). Usage: | 8 // during image decoding on supported platforms (default off). Usage: |
9 // | 9 // |
10 // % ninja -C out/Release image_decode_bench && | 10 // % ninja -C out/Release image_decode_bench && |
(...skipping 23 matching lines...) Expand all Loading... |
34 #else | 34 #else |
35 #include <sys/stat.h> | 35 #include <sys/stat.h> |
36 #include <sys/time.h> | 36 #include <sys/time.h> |
37 typedef struct stat sttype; | 37 typedef struct stat sttype; |
38 #endif | 38 #endif |
39 | 39 |
40 using namespace blink; | 40 using namespace blink; |
41 | 41 |
42 #if defined(_WIN32) | 42 #if defined(_WIN32) |
43 | 43 |
44 // There is no real platform support herein, so adopt the WIN32 performance coun
ter from | 44 // There is no real platform support herein, so adopt the WIN32 performance |
45 // WTF http://trac.webkit.org/browser/trunk/Source/WTF/wtf/CurrentTime.cpp?rev=1
52438 | 45 // counter from WTF |
| 46 // http://trac.webkit.org/browser/trunk/Source/WTF/wtf/CurrentTime.cpp?rev=15243
8 |
46 | 47 |
47 static double lowResUTCTime() { | 48 static double lowResUTCTime() { |
48 FILETIME fileTime; | 49 FILETIME fileTime; |
49 GetSystemTimeAsFileTime(&fileTime); | 50 GetSystemTimeAsFileTime(&fileTime); |
50 | 51 |
51 // As per Windows documentation for FILETIME, copy the resulting FILETIME stru
cture to a | 52 // As per Windows documentation for FILETIME, copy the resulting FILETIME |
52 // ULARGE_INTEGER structure using memcpy (using memcpy instead of direct assig
nment can | 53 // structure to a ULARGE_INTEGER structure using memcpy (using memcpy instead |
53 // prevent alignment faults on 64-bit Windows). | 54 // of direct assignment can prevent alignment faults on 64-bit Windows). |
54 ULARGE_INTEGER dateTime; | 55 ULARGE_INTEGER dateTime; |
55 memcpy(&dateTime, &fileTime, sizeof(dateTime)); | 56 memcpy(&dateTime, &fileTime, sizeof(dateTime)); |
56 | 57 |
57 // Number of 100 nanosecond between January 1, 1601 and January 1, 1970. | 58 // Number of 100 nanosecond between January 1, 1601 and January 1, 1970. |
58 static const ULONGLONG epochBias = 116444736000000000ULL; | 59 static const ULONGLONG epochBias = 116444736000000000ULL; |
59 // Windows file times are in 100s of nanoseconds. | 60 // Windows file times are in 100s of nanoseconds. |
60 static const double hundredsOfNanosecondsPerMillisecond = 10000; | 61 static const double hundredsOfNanosecondsPerMillisecond = 10000; |
61 return (dateTime.QuadPart - epochBias) / hundredsOfNanosecondsPerMillisecond; | 62 return (dateTime.QuadPart - epochBias) / hundredsOfNanosecondsPerMillisecond; |
62 } | 63 } |
63 | 64 |
64 static LARGE_INTEGER qpcFrequency; | 65 static LARGE_INTEGER qpcFrequency; |
65 static bool syncedTime; | 66 static bool syncedTime; |
66 | 67 |
67 static double highResUpTime() { | 68 static double highResUpTime() { |
68 // We use QPC, but only after sanity checking its result, due to bugs: | 69 // We use QPC, but only after sanity checking its result, due to bugs: |
69 // http://support.microsoft.com/kb/274323 http://support.microsoft.com/kb/8959
80 | 70 // http://support.microsoft.com/kb/274323 |
70 // http://msdn.microsoft.com/en-us/library/ms644904.aspx ("you can get differe
nt results | 71 // http://support.microsoft.com/kb/895980 |
71 // on different processors due to bugs in the basic input/output system (BIOS)
or the | 72 // http://msdn.microsoft.com/en-us/library/ms644904.aspx ("you can get |
72 // hardware abstraction layer (HAL)."). | 73 // different results on different processors due to bugs in the basic |
| 74 // input/output system (BIOS) or the hardware abstraction layer (HAL)."). |
73 | 75 |
74 static LARGE_INTEGER qpcLast; | 76 static LARGE_INTEGER qpcLast; |
75 static DWORD tickCountLast; | 77 static DWORD tickCountLast; |
76 static bool inited; | 78 static bool inited; |
77 | 79 |
78 LARGE_INTEGER qpc; | 80 LARGE_INTEGER qpc; |
79 QueryPerformanceCounter(&qpc); | 81 QueryPerformanceCounter(&qpc); |
80 DWORD tickCount = GetTickCount(); | 82 DWORD tickCount = GetTickCount(); |
81 | 83 |
82 if (inited) { | 84 if (inited) { |
83 __int64 qpcElapsed = | 85 __int64 qpcElapsed = |
84 ((qpc.QuadPart - qpcLast.QuadPart) * 1000) / qpcFrequency.QuadPart; | 86 ((qpc.QuadPart - qpcLast.QuadPart) * 1000) / qpcFrequency.QuadPart; |
85 __int64 tickCountElapsed; | 87 __int64 tickCountElapsed; |
86 if (tickCount >= tickCountLast) { | 88 if (tickCount >= tickCountLast) { |
87 tickCountElapsed = (tickCount - tickCountLast); | 89 tickCountElapsed = (tickCount - tickCountLast); |
88 } else { | 90 } else { |
89 __int64 tickCountLarge = tickCount + 0x100000000I64; | 91 __int64 tickCountLarge = tickCount + 0x100000000I64; |
90 tickCountElapsed = tickCountLarge - tickCountLast; | 92 tickCountElapsed = tickCountLarge - tickCountLast; |
91 } | 93 } |
92 | 94 |
93 // Force a re-sync if QueryPerformanceCounter differs from GetTickCount() by
more than | 95 // Force a re-sync if QueryPerformanceCounter differs from GetTickCount() by |
94 // 500ms. (The 500ms value is from http://support.microsoft.com/kb/274323). | 96 // more than 500ms. (The 500ms value is from |
| 97 // http://support.microsoft.com/kb/274323). |
95 __int64 diff = tickCountElapsed - qpcElapsed; | 98 __int64 diff = tickCountElapsed - qpcElapsed; |
96 if (diff > 500 || diff < -500) | 99 if (diff > 500 || diff < -500) |
97 syncedTime = false; | 100 syncedTime = false; |
98 } else { | 101 } else { |
99 inited = true; | 102 inited = true; |
100 } | 103 } |
101 | 104 |
102 qpcLast = qpc; | 105 qpcLast = qpc; |
103 tickCountLast = tickCount; | 106 tickCountLast = tickCount; |
104 | 107 |
105 return (1000.0 * qpc.QuadPart) / static_cast<double>(qpcFrequency.QuadPart); | 108 return (1000.0 * qpc.QuadPart) / static_cast<double>(qpcFrequency.QuadPart); |
106 } | 109 } |
107 | 110 |
108 static bool qpcAvailable() { | 111 static bool qpcAvailable() { |
109 static bool available; | 112 static bool available; |
110 static bool checked; | 113 static bool checked; |
111 | 114 |
112 if (checked) | 115 if (checked) |
113 return available; | 116 return available; |
114 | 117 |
115 available = QueryPerformanceFrequency(&qpcFrequency); | 118 available = QueryPerformanceFrequency(&qpcFrequency); |
116 checked = true; | 119 checked = true; |
117 return available; | 120 return available; |
118 } | 121 } |
119 | 122 |
120 static double getCurrentTime() { | 123 static double getCurrentTime() { |
121 // Use a combination of ftime and QueryPerformanceCounter. | 124 // Use a combination of ftime and QueryPerformanceCounter. |
122 // ftime returns the information we want, but doesn't have sufficient resoluti
on. | 125 // ftime returns the information we want, but doesn't have sufficient |
123 // QueryPerformanceCounter has high resolution, but is only usable to measure
time intervals. | 126 // resolution. QueryPerformanceCounter has high resolution, but is only |
124 // To combine them, we call ftime and QueryPerformanceCounter initially. Later
calls will | 127 // usable to measure time intervals. To combine them, we call ftime and |
125 // use QueryPerformanceCounter by itself, adding the delta to the saved ftime. | 128 // QueryPerformanceCounter initially. Later calls will use |
126 // We periodically re-sync to correct for drift. | 129 // QueryPerformanceCounter by itself, adding the delta to the saved ftime. We |
| 130 // periodically re-sync to correct for drift. |
127 static double syncLowResUTCTime; | 131 static double syncLowResUTCTime; |
128 static double syncHighResUpTime; | 132 static double syncHighResUpTime; |
129 static double lastUTCTime; | 133 static double lastUTCTime; |
130 | 134 |
131 double lowResTime = lowResUTCTime(); | 135 double lowResTime = lowResUTCTime(); |
132 if (!qpcAvailable()) | 136 if (!qpcAvailable()) |
133 return lowResTime * (1.0 / 1000.0); | 137 return lowResTime * (1.0 / 1000.0); |
134 | 138 |
135 double highResTime = highResUpTime(); | 139 double highResTime = highResUpTime(); |
136 if (!syncedTime) { | 140 if (!syncedTime) { |
137 timeBeginPeriod(1); // increase time resolution around low-res time getter | 141 timeBeginPeriod(1); // increase time resolution around low-res time getter |
138 syncLowResUTCTime = lowResTime = lowResUTCTime(); | 142 syncLowResUTCTime = lowResTime = lowResUTCTime(); |
139 timeEndPeriod(1); // restore time resolution | 143 timeEndPeriod(1); // restore time resolution |
140 syncHighResUpTime = highResTime; | 144 syncHighResUpTime = highResTime; |
141 syncedTime = true; | 145 syncedTime = true; |
142 } | 146 } |
143 | 147 |
144 double highResElapsed = highResTime - syncHighResUpTime; | 148 double highResElapsed = highResTime - syncHighResUpTime; |
145 double utc = syncLowResUTCTime + highResElapsed; | 149 double utc = syncLowResUTCTime + highResElapsed; |
146 | 150 |
147 // Force a clock re-sync if we've drifted. | 151 // Force a clock re-sync if we've drifted. |
148 double lowResElapsed = lowResTime - syncLowResUTCTime; | 152 double lowResElapsed = lowResTime - syncLowResUTCTime; |
149 const double maximumAllowedDriftMsec = | 153 const double maximumAllowedDriftMsec = |
150 15.625 * 2.0; // 2x the typical low-res accuracy | 154 15.625 * 2.0; // 2x the typical low-res accuracy |
151 if (fabs(highResElapsed - lowResElapsed) > maximumAllowedDriftMsec) | 155 if (fabs(highResElapsed - lowResElapsed) > maximumAllowedDriftMsec) |
152 syncedTime = false; | 156 syncedTime = false; |
153 | 157 |
154 // Make sure time doesn't run backwards (only correct if the difference is < 2
seconds, | 158 // Make sure time doesn't run backwards (only correct if the difference is < 2 |
155 // since DST or clock changes could occur). | 159 // seconds, since DST or clock changes could occur). |
156 const double backwardTimeLimit = 2000.0; | 160 const double backwardTimeLimit = 2000.0; |
157 if (utc < lastUTCTime && (lastUTCTime - utc) < backwardTimeLimit) | 161 if (utc < lastUTCTime && (lastUTCTime - utc) < backwardTimeLimit) |
158 return lastUTCTime * (1.0 / 1000.0); | 162 return lastUTCTime * (1.0 / 1000.0); |
159 | 163 |
160 lastUTCTime = utc; | 164 lastUTCTime = utc; |
161 return utc * (1.0 / 1000.0); | 165 return utc * (1.0 / 1000.0); |
162 } | 166 } |
163 | 167 |
164 #else | 168 #else |
165 | 169 |
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
395 exit(3); | 399 exit(3); |
396 } | 400 } |
397 } | 401 } |
398 | 402 |
399 // Results to stdout. | 403 // Results to stdout. |
400 | 404 |
401 double averageTime = totalTime / static_cast<double>(iterations); | 405 double averageTime = totalTime / static_cast<double>(iterations); |
402 printf("%f %f\n", totalTime, averageTime); | 406 printf("%f %f\n", totalTime, averageTime); |
403 return 0; | 407 return 0; |
404 } | 408 } |
OLD | NEW |