void RunParallelScalarTests(const char *test_name) { tbb::task_scheduler_init init(tbb::task_scheduler_init::deferred); for (int p = MinThread; p <= MaxThread; ++p) { if (p == 0) continue; REMARK("Testing parallel %s on %d thread(s)... ", test_name, p); init.initialize(p); tbb::tick_count t0; T assign_sum(0); T combine_sum(0); T combine_ref_sum(0); T combine_each_sum(0); T combine_finit_sum(0); for (int t = -1; t < REPETITIONS; ++t) { if (Verbose && t == 0) t0 = tbb::tick_count::now(); tbb::combinable<T> sums; FunctorAddFinit<T> my_finit_decl; tbb::combinable<T> finit_combinable(my_finit_decl); tbb::parallel_for( tbb::blocked_range<int>( 0, N, 10000 ), ParallelScalarBodyNoInit<T>( finit_combinable ) ); tbb::parallel_for( tbb::blocked_range<int>( 0, N, 10000 ), ParallelScalarBody<T>( sums ) ); // Use combine combine_sum += sums.combine(my_combine<T>); combine_ref_sum += sums.combine(my_combine_ref<T>); CombineEachHelper<T> my_helper(combine_each_sum); sums.combine_each(my_helper); // test assignment tbb::combinable<T> assigned; assigned = sums; assign_sum += assigned.combine(my_combine<T>); combine_finit_sum += finit_combinable.combine(my_combine<T>); } ASSERT( EXPECTED_SUM == combine_sum, NULL); ASSERT( EXPECTED_SUM == combine_ref_sum, NULL); ASSERT( EXPECTED_SUM == assign_sum, NULL); ASSERT( EXPECTED_SUM == combine_finit_sum, NULL); REMARK("done\nparallel %s, %d, %g, %g\n", test_name, p, static_cast<double>(combine_sum), ( tbb::tick_count::now() - t0).seconds()); init.terminate(); } }
void run_parallel_scalar_tests(const char *test_name) { typedef tbb::enumerable_thread_specific<T> ets_type; // We assume that static_sums zero-initialized or has a default constructor that zeros it. static ets_type static_sums = ets_type( T() ); T exemplar; test_helper<T>::init(exemplar); run_parallel_scalar_tests_nocombine<T>(test_name); for (int p = MinThread; p <= MaxThread; ++p) { REMARK("Testing parallel %s on %d thread(s)... ", test_name, p); tbb::task_scheduler_init init(p); tbb::tick_count t0; T combine_sum; test_helper<T>::init(combine_sum); T combine_ref_sum; test_helper<T>::init(combine_ref_sum); T combine_one_sum; test_helper<T>::init(combine_one_sum); T static_sum; test_helper<T>::init(static_sum); for (int t = -1; t < REPETITIONS; ++t) { if (Verbose && t == 0) t0 = tbb::tick_count::now(); static_sums.clear(); ets_type sums(exemplar); ASSERT( sums.empty(), NULL); tbb::parallel_for( tbb::blocked_range<int>( 0, N, 10000 ), parallel_scalar_body<T>( sums ) ); ASSERT( !sums.empty(), NULL); ASSERT(static_sums.empty(), NULL); tbb::parallel_for( tbb::blocked_range<int>( 0, N, 10000 ), parallel_scalar_body<T>( static_sums ) ); ASSERT( !static_sums.empty(), NULL); // Use combine test_helper<T>::sum(combine_sum, sums.combine(my_combine<T>)); test_helper<T>::sum(combine_ref_sum, sums.combine(my_combine_ref<T>)); test_helper<T>::sum(static_sum, static_sums.combine(my_combine<T>)); combine_one_helper<T> my_helper(combine_one_sum); sums.combine_each(my_helper); } ASSERT( EXPECTED_SUM == test_helper<T>::get(combine_sum), NULL); ASSERT( EXPECTED_SUM == test_helper<T>::get(combine_ref_sum), NULL); ASSERT( EXPECTED_SUM == test_helper<T>::get(static_sum), NULL); REMARK("done\nparallel combine %s, %d, %g, %g\n", test_name, p, test_helper<T>::get(combine_sum), ( tbb::tick_count::now() - t0).seconds()); } }