13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*------------------------------------------------------------------------- 23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Quality Program Tester Core 33c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * ---------------------------------------- 43c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 53c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Copyright 2014 The Android Open Source Project 63c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 73c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Licensed under the Apache License, Version 2.0 (the "License"); 83c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * you may not use this file except in compliance with the License. 93c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * You may obtain a copy of the License at 103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * http://www.apache.org/licenses/LICENSE-2.0 123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Unless required by applicable law or agreed to in writing, software 143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * distributed under the License is distributed on an "AS IS" BASIS, 153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * See the License for the specific language governing permissions and 173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * limitations under the License. 183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*! 203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \file 213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief CPU warm-up utility, used to counteract CPU throttling. 223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuCPUWarmup.hpp" 253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deDefs.hpp" 263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deMath.h" 273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deClock.h" 283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <algorithm> 303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 313c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace tcu 323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 343c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace warmupCPUInternal 353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 373c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvolatile Dummy g_dummy; 383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 413c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, int Size> 423c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline float floatMedian (const T (&v)[Size]) 433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry T temp[Size]; 453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int i = 0; i < Size; i++) 463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry temp[i] = v[i]; 473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::sort(DE_ARRAY_BEGIN(temp), DE_ARRAY_END(temp)); 493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return Size % 2 == 0 513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ? 0.5f * ((float)temp[Size/2-1] + (float)temp[Size/2]) 523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : (float)temp[Size/2]; 533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 553c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, int Size> 563c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline float floatRelativeMedianAbsoluteDeviation (const T (&v)[Size]) 573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const float median = floatMedian(v); 593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry float absoluteDeviations[Size]; 603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int i = 0; i < Size; i++) 623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry absoluteDeviations[i] = deFloatAbs((float)v[i] - median); 633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return floatMedian(absoluteDeviations) / median; 653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 673c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline float dummyComputation (float initial, int numIterations) 683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry float a = initial; 703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int b = 123; 713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int i = 0; i < numIterations; i++) 733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Arbitrary computations. 753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int j = 0; j < 4; j++) 763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry a = deFloatCos(a + (float)b); 783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry b = (b + 63) % 107 + de::abs((int)(a*10.0f)); 793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return a + (float)b; 833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 853c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid warmupCPU (void) 863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry float dummy = *warmupCPUInternal::g_dummy.m_v; 883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int computationSize = 1; 893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Do a rough calibration for computationSize to get dummyComputation's running time above a certain threshold. 913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry while (computationSize < 1<<30) // \note This condition is unlikely to be met. The "real" loop exit is the break below. 923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const float singleMeasurementThreshold = 10000.0f; 943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numMeasurements = 3; 953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deInt64 times[numMeasurements]; 963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int i = 0; i < numMeasurements; i++) 983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint64 startTime = deGetMicroseconds(); 1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry dummy = dummyComputation(dummy, computationSize); 1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry times[i] = (deInt64)(deGetMicroseconds() - startTime); 1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (floatMedian(times) >= singleMeasurementThreshold) 1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry computationSize *= 2; 1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Do dummyComputations until running time seems stable enough. 1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int maxNumMeasurements = 50; 1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numConsecutiveMeasurementsRequired = 5; 1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const float relativeMedianAbsoluteDeviationThreshold = 0.05f; 1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deInt64 latestTimes[numConsecutiveMeasurementsRequired]; 1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int measurementNdx = 0; 1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry measurementNdx < maxNumMeasurements && 1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (measurementNdx < numConsecutiveMeasurementsRequired || 1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry floatRelativeMedianAbsoluteDeviation(latestTimes) > relativeMedianAbsoluteDeviationThreshold); 1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry measurementNdx++) 1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint64 startTime = deGetMicroseconds(); 1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry dummy = dummyComputation(dummy, computationSize); 1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry latestTimes[measurementNdx % numConsecutiveMeasurementsRequired] = (deInt64)(deGetMicroseconds() - startTime); 1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *warmupCPUInternal::g_dummy.m_v = dummy; 1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // tcu 135