| 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 |