void App::onRender() { // Show message message("Rendering..."); Stopwatch timer; rayTraceImage(1.0f, m_raysPerPixel); timer.after("Trace"); debugPrintf("%f s\n", timer.elapsedTime()); // m_result->toImage3uint8()->save("result.png"); }
int main(int argc, char *argv[]) { int test = argc > 1 ? atoi(argv[1]) : 0; int verbose = argc > 2; int veryVerbose = argc > 3; int veryVeryVerbose = argc > 4; (void) veryVeryVerbose; printf("TEST " __FILE__ " CASE %d\n", test); switch (test) { case 0: // Zero is always the leading case. case 5: { // -------------------------------------------------------------------- // TESTING USAGE EXAMPLE 3 // This will test the usage example 3 provided in the component // header file for 'prefetchForReading' and 'prefetchForWriting'. // // Concerns: // The usage example provided in the component header file must // compile, link, and run on all platforms as shown. // // Plan: // Run the usage example using 'prefetchForReading' and // 'prefetchForWriting'. // // Testing: // prefetchForReading // prefetchForWriting // -------------------------------------------------------------------- if (verbose) printf("\nTESTING USAGE EXAMPLE 3" "\n=======================\n"); UsageExample3Case::testUsageExample3(argc, false); } break; case 4: { // -------------------------------------------------------------------- // TESTING USAGE EXAMPLE 2 // This will test the usage example 2 provided in the component // header file for 'BSLS_PERFORMANCEHINT_PREDICT_EXPECT'. // // Concerns: // The usage example provided in the component header file must // compile, link, and run on all platforms as shown. // // Plan: // Ensure the usage example compiles. // // Testing: // BSLS_PERFORMANCEHINT_PREDICT_EXPECT // -------------------------------------------------------------------- if (verbose) printf("\nTESTING USAGE EXAMPLE 2" "\n=======================\n"); int x = rand() % 4; // Incorrect usage of 'BSLS_PERFORMANCEHINT_PREDICT_EXPECT', since the // probability of getting a 3 is equivalent to other numbers (0, 1, 2). // However, this is sufficient to illustrate the intent of this macro. switch(BSLS_PERFORMANCEHINT_PREDICT_EXPECT(x, 3)) { case 1: //.. break; case 2: //.. break; case 3: //.. break; default: break; } } break; case 3: { // -------------------------------------------------------------------- // TESTING USAGE EXAMPLE 1 // This will test the usage example 1 provided in the component // header file for 'BSLS_PERFORMANCEHINT_PREDICT_LIKELY' and // 'BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY'. // // Concerns: // The usage example provided in the component header file must // compile, link, and run on all platforms as shown. // // Plan: // Run the usage example using 'BSLS_PERFORMANCEHINT_PREDICT_LIKELY' // and 'BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY'. // // Testing: // BSLS_PERFORMANCEHINT_PREDICT_LIKELY, // BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY // -------------------------------------------------------------------- if (verbose) printf("\nTESTING USAGE EXAMPLE 1" "\n=======================\n"); ASSERT(true); UsageExample1Case::testUsageExample1(argc, true); } break; case 2: { // -------------------------------------------------------------------- // TESTING: BSLS_PERFORMANCEHINT_OPTIMIZATION_FENCE // // Concerns: //: 1 'OPTIMIZATION_FENCE' compiles on all platforms. //: //: 2 On platforms on which it is reasonably implemented, //: 'OPTIMIZATION_FENCE' impedes compiler optimizations on optimized //: builds. // // Plan: //: 1 Perform a simple loop incrementing a counter for a set period of //: time, both with and without the use of the 'OPTMIZATION_FENCE'. //: Use a timer to verify the rate of increments using the //: 'OPTIMIZATION_FENCE' is slower. Note that in practice, on //: platforms on which the fence is reasonably implemented (*not* //: older versions of Sun CC), the iteration with the //: 'OPTIMIZATION_FENCE" is very noticeably slower (several times //: slower). // // Testing: // BSLS_PERFORMANCEHINT_OPTIMIZATION_FENCE // -------------------------------------------------------------------- if (verbose) printf( "\nTESTING: BSLS_PERFORMANCEHINT_OPTIMIZATION_FENCE" "\n================================================\n"); ReorderingFenceTestCase::testReorderingFence(argc); } break; case 1: { // -------------------------------------------------------------------- // TESTING TEST-MACHINERY: 'Stopwatch' // // Concerns: //: 1 That 'Stopwatch' is created in a STOPPED state with an elapsed //: time of 0. //: //: 2 That 'start' puts the stopwatch in a RUNNING state //: //: 3 That 'stop' puts the soptwatch in a STOPPED state and recurds //: the accumuted time. //: //: 4 That 'elaspsedTime' returns the correct elapsed time in //: nanoseconds. //: //: 5 That 'reset' resets the 'Stopwatch' to its defualt constructed //: state. // // Plan: //: 1 Construct a 'Stopwatch' and verify 'isRunning' is 'false' and //: 'elapsedTime' is 0. (C-1) //: //: 2 Construct a 'Stopwatch', call 'start', sleep for ~1 second and //: verify 'isRunning' it 'true' and 'elapsedTime' is ~1 second. //: //: 2 Construct a 'Stopwatch', call 'start', sleep for ~1 second and //: then stop the 'Stopwatch'. Sleep another second. Verify //: 'isRunning' it 'false', 'elapsedTime' is ~1, and that the elapsed //: time has not changed since the stopwatch was stopped. // // Testing: // TESTING TEST-MACHINERY: 'Stopwatch' // -------------------------------------------------------------------- if (verbose) printf("\nTESTING TEST-MACHINERY: 'Stopwatch'" "\n===================================\n"); const double TOLERANCE = .5; if (veryVerbose) printf("\tCompare constructed 'Stopwatch'\n"); { Stopwatch mX; const Stopwatch& X = mX; ASSERT(false == X.isRunning()); ASSERT(0 == X.elapsedTime()); } if (veryVerbose) printf("Test starting a stopwatch\n"); { Stopwatch mX; const Stopwatch& X = mX; ASSERT(false == X.isRunning()); ASSERT(0 == X.elapsedTime()); mX.start(); sleep(1); ASSERT(true == X.isRunning()); ASSERT(1 - TOLERANCE < X.elapsedTime()); ASSERT(1 + TOLERANCE > X.elapsedTime()); } if (veryVerbose) printf("Test stop and elapsedTime\n"); { Stopwatch mX; const Stopwatch& X = mX; ASSERT(false == X.isRunning()); ASSERT(0 == X.elapsedTime()); mX.start(); sleep(1); ASSERT(true == X.isRunning()); ASSERT(0 < X.elapsedTime()); mX.stop(); double EXPECTED = X.elapsedTime(); sleep(1); double ACTUAL = X.elapsedTime(); ASSERTV(EXPECTED, ACTUAL, EXPECTED - EXPECTED * .00001 < ACTUAL && EXPECTED + EXPECTED * .00001 > ACTUAL); ASSERTV(X.elapsedTime(), 1 - TOLERANCE < X.elapsedTime()); ASSERTV(X.elapsedTime(), 1 + TOLERANCE > X.elapsedTime()); mX.reset(); ASSERT(false == X.isRunning()); ASSERT(0 == X.elapsedTime()); } } break; case -1: { // -------------------------------------------------------------------- // PERFORMANCE TEST // Test the improvement of performance in using various performance // hints. // // Concerns: // The performance of using the performance hints in the various // usage examples must be faster than not using them. // // Plan: // Using 'Stopwatch', compare the time it takes to run the test // using the performance hints and not using the hints. Then compare // and assert the time difference. The test driver must observe an // improvement in performance. To minimize the effect of caching // biasing the result, run the version that uses the proper hint // first. // // Testing: // PERFORMANCE TEST // -------------------------------------------------------------------- if (verbose) printf("\nPERFORMANCE TEST" "\n================\n"); if (veryVerbose) { printf("Usage Example 1:\n"); } UsageExample1Case::testUsageExample1(argc, true); if (veryVerbose) { printf("Usage Example 3:\n"); } UsageExample3Case::testUsageExample3(argc, true); } break; case -2: { // -------------------------------------------------------------------- // CONCERN: STOPWATCH ACCURACY // This test is concerned with the accuracy of 'Stopwatch'. It is a // negative test case because it takes ~1 minute to run. // Concerns: //: 1 That the 'elapsedTime' reported by 'Stopwatch' is accurate. // // Plan: //: 1 Perform a loop-based tested, sleeping over a series of different //: delay periods and comparing the results of //: 'Stopwatch::elapsedTime' to 'time' // // Testing: // CONCERN: STOPWATCH ACCURACY // -------------------------------------------------------------------- if (verbose) printf("\nCONCERN: STOPWATCH ACCURACY" "\n===========================\n"); if (veryVerbose) printf("\tCompare results w/ 'time'\n"); for (int i = 1; i < 7; ++i){ const int DELAY = i; time_t startTime = time(0); Stopwatch mX; mX.start(); sleep(DELAY); mX.stop(); time_t expectedElaspedTime = time(0) - startTime; if (veryVerbose) { P_(DELAY); P_(mX.elapsedTime()); P(expectedElaspedTime); } ASSERT(mX.elapsedTime() < expectedElaspedTime + 1 && mX.elapsedTime() > expectedElaspedTime - 1); } } break; default: { fprintf(stderr, "WARNING: CASE `%d' NOT FOUND.\n", test); testStatus = -1; } } if (testStatus > 0) { fprintf(stderr, "Error, non-zero test status = %d.\n", testStatus); } return testStatus; }
void testReorderingFence(int argc) { int verbose = argc > 2; int veryVerbose = argc > 3; int veryVeryVerbose = argc > 4; // suppress 'unused parameter' compiler warnings: (void) verbose; (void) veryVeryVerbose; enum { CHUNK_SIZE = 1000 }; double rateWithFence; double rateWithoutFence; if (veryVerbose) { printf("With BSLS_PERFORMANCEHINT_OPTIMIZATION_FENCE\n"); } { Stopwatch timer; timer.start(); double elapsedTime = 0; int iterations = 0; int numChunks = 0; while (elapsedTime <= .4) { for (int i = 0; i < CHUNK_SIZE; ++i) { iterations++; BSLS_PERFORMANCEHINT_OPTIMIZATION_FENCE; } ++numChunks; elapsedTime = timer.elapsedTime(); } rateWithFence = numChunks/elapsedTime; } if (veryVerbose) { printf("\trate = %f\n", rateWithFence); } if (veryVerbose) { printf("Without BSLS_PERFORMANCEHINT_OPTIMIZATION_FENCE\n"); } { Stopwatch timer; timer.start(); double elapsedTime = 0; int iterations = 0; int numChunks = 0; while (elapsedTime <= .4) { for (int i = 0; i < CHUNK_SIZE; ++i) { iterations++; } ++numChunks; elapsedTime = timer.elapsedTime(); } rateWithoutFence = numChunks/elapsedTime; } if (veryVerbose) { printf("\trate = %f\n", rateWithoutFence); } #if defined(BDE_BUILD_TARGET_OPT) && \ !(defined(BSLS_PLATFORM_CMP_SUN) && (BSLS_PLATFORM_CMP_VERSION < 0x5110)) // Perform this test only for optimized builds. Also older Sun compilers // do not support this fence. LOOP2_ASSERT(rateWithFence, rateWithoutFence, rateWithFence < rateWithoutFence); #endif }
void testUsageExample3(int argc, bool assert) { int verbose = argc > 2; int veryVerbose = argc > 3; int veryVeryVerbose = argc > 4; // suppress 'unused parameter' compiler warnings: (void) assert; (void) verbose; (void) veryVeryVerbose; if (veryVerbose) { printf("Adding without prefetch\n"); } UsageExample3Case::init(UsageExample3Case::array1, UsageExample3Case::array2); Stopwatch timer; timer.start(); for(int i = 0; i < TESTSIZE; ++i) { UsageExample3Case::addWithoutPrefetch(UsageExample3Case::array1, UsageExample3Case::array2); } timer.stop(); double withoutPrefetch = timer.elapsedTime(); if (veryVerbose) { P(withoutPrefetch); } if (veryVerbose) { printf("Adding with prefetch\n"); } UsageExample3Case::init(UsageExample3Case::array3, UsageExample3Case::array4); timer.reset(); timer.start(); for(int i = 0; i < UsageExample3Case::TESTSIZE; ++i) { addWithPrefetch(array3, array4); } timer.stop(); double withPrefetch = timer.elapsedTime(); if (veryVerbose) { P(withPrefetch); } #if defined(BDE_BUILD_TARGET_OPT) // Only check under optimized build. #if defined(BSLS_PLATFORM_CMP_CLANG) \ || defined(BSLS_PLATFORM_CMP_GNU) \ || defined(BSLS_PLATFORM_CMP_SUN) \ || defined(BSLS_PLATFORM_CMP_IBM) \ || defined(BSLS_PLATFORM_OS_WINDOWS) // Only check when 'prefetchForReading' or 'prefetchForWriting' expands // expands into something meaningful. double tolerance = 0.02; // Note that when compiling using 'bde_build.pl -t opt_exc_mt', the // optimization flag is set to '-O'. Whereas, the optimization flag used // by 'IS_OPTIMIZED=1 pcomp' is set to '-xO2'. Therefore, the improvement // in efficiency is much less than what's described in the usage example // when compiled using bde_build. if (assert) { // Only assert in performance test case. LOOP2_ASSERT(withoutPrefetch, withPrefetch, withoutPrefetch + tolerance > withPrefetch); } #endif #endif }
void testUsageExample1(int argc, bool assert) { int verbose = argc > 2; int veryVerbose = argc > 3; int veryVeryVerbose = argc > 4; double tolerance = 0.05; (void) assert; (void) verbose; (void) veryVerbose; (void) veryVeryVerbose; (void) tolerance; Stopwatch timer; timer.reset(); if (veryVerbose) { printf("BSLS_PERFORMANCEHINT_PREDICT_LIKELY\n"); } timer.start(); for (int x = 0; x < TESTSIZE; ++x) { int y = rand() % 100; // Incorrect usage of 'BSLS_PERFORMANCEHINT_PREDICT_LIKELY' since there // is only a one in 100 chance that this branch is taken. if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(y == 8)) { foo(); } else { BSLS_PERFORMANCEHINT_UNLIKELY_HINT; bar(); } } timer.stop(); double likelyTime = timer.elapsedTime(); if (veryVerbose) { P(likelyTime); } if (veryVerbose) { printf("BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY\n"); } timer.reset(); timer.start(); for (int x = 0; x < TESTSIZE; ++x) { int y = rand() % 100; // Correct usage of 'BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY' since there // is only a one in 100 chance that this branch is taken. if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(y == 8)) { BSLS_PERFORMANCEHINT_UNLIKELY_HINT; foo(); } else { bar(); } } timer.stop(); double unlikelyTime = timer.elapsedTime(); if (veryVerbose) { P(unlikelyTime); } #if defined(BDE_BUILD_TARGET_OPT) // Only check under optimized build. #if defined(BSLS_PLATFORM_CMP_CLANG) \ || defined(BSLS_PLATFORM_CMP_GNU) \ || defined(BSLS_PLATFORM_CMP_SUN) \ || (defined(BSLS_PLATFORM_CMP_IBM) && BSLS_PLATFORM_CMP_VERSION >= 0x0900) // Only check when 'BSLS_PERFORMANCEHINT_PREDICT_LIKELY' and // 'BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY' expands into something // meaningful. if (assert) { LOOP2_ASSERT(likelyTime, unlikelyTime, likelyTime + tolerance > unlikelyTime); } #endif #endif }