|
Teuchos Package Browser (Single Doxygen Collection)
Version of the Day
|
00001 /* 00002 // @HEADER 00003 // *********************************************************************** 00004 // 00005 // Teuchos: Common Tools Package 00006 // Copyright (2004) Sandia Corporation 00007 // 00008 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive 00009 // license for use of this work by or on behalf of the U.S. Government. 00010 // 00011 // Redistribution and use in source and binary forms, with or without 00012 // modification, are permitted provided that the following conditions are 00013 // met: 00014 // 00015 // 1. Redistributions of source code must retain the above copyright 00016 // notice, this list of conditions and the following disclaimer. 00017 // 00018 // 2. Redistributions in binary form must reproduce the above copyright 00019 // notice, this list of conditions and the following disclaimer in the 00020 // documentation and/or other materials provided with the distribution. 00021 // 00022 // 3. Neither the name of the Corporation nor the names of the 00023 // contributors may be used to endorse or promote products derived from 00024 // this software without specific prior written permission. 00025 // 00026 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY 00027 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00028 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 00029 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE 00030 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00031 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00032 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00033 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00034 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00035 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00036 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00037 // 00038 // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 00039 // 00040 // *********************************************************************** 00041 // @HEADER 00042 */ 00043 00044 #include "Teuchos_UnitTestHarness.hpp" 00045 #include "Teuchos_TabularOutputter.hpp" 00046 00047 #include "Teuchos_Array.hpp" 00048 00049 00050 namespace { 00051 00052 00053 using Teuchos::null; 00054 using Teuchos::RCP; 00055 using Teuchos::rcp; 00056 using Teuchos::TabularOutputter; 00057 using Teuchos::Ordinal; 00058 00059 00060 double relCpuSpeed = 1e-2; 00061 int maxArraySize = 10000; 00062 double maxArrayBracketRatio =100.0; 00063 double maxArrayIterRatio = 100.0; 00064 double maxArrayRCPSelfIterRatio =200.0; 00065 00066 const int minArraySize = 100; 00067 const int maxLoopIters = 1000; 00068 const int intPrec = 8; 00069 const int dblPrec = 6; 00070 00071 TEUCHOS_STATIC_SETUP() 00072 { 00073 Teuchos::CommandLineProcessor &clp = 00074 Teuchos::UnitTestRepository::getCLP(); 00075 clp.setOption( 00076 "rel-cpu-speed", &relCpuSpeed, 00077 "The relative speed of the CPU (higher means the machine runs faster)" 00078 ); 00079 clp.setOption( 00080 "max-array-size", &maxArraySize, 00081 "The maximum size of the arrays created" 00082 ); 00083 clp.setOption( 00084 "max-array-bracket-ratio", &maxArrayBracketRatio, 00085 "The max allowed CPU timing ratio of the Array[RCP,View] braket operator relative" 00086 " to the std::vector braket operator." 00087 ); 00088 clp.setOption( 00089 "max-array-iter-ratio", &maxArrayIterRatio, 00090 "The max allowed CPU timing ratio of the Array[RCP,View] iterators relative" 00091 " to using raw pointers as iterators." 00092 ); 00093 clp.setOption( 00094 "max-arrayrcp-self-iter-ratio", &maxArrayRCPSelfIterRatio, 00095 "The max allowed CPU timing ratio of the ArrayrCP as a self iterator relative" 00096 " to raw pointer arithmetic." 00097 ); 00098 } 00099 00100 00101 TEUCHOS_UNIT_TEST( Array, braketOperatorOverhead ) 00102 { 00103 00104 typedef Teuchos::TabularOutputter TO; 00105 00106 const double relTestCost = 1e-4; 00107 00108 const double numInnerLoops = relCpuSpeed / relTestCost; 00109 00110 out << "\n" 00111 << "Measuring the overhead of the Array braket operator relative to raw pointers.\n" 00112 << "\n" 00113 << "Number of loops = relCpuSpeed/relTestCost = " 00114 << relCpuSpeed << "/" << relTestCost << " = " << numInnerLoops << "\n" 00115 << "\n"; 00116 00117 TabularOutputter outputter(out); 00118 outputter.setFieldTypePrecision(TO::DOUBLE, dblPrec); 00119 outputter.setFieldTypePrecision(TO::INT, intPrec); 00120 00121 outputter.pushFieldSpec("array dim", TO::INT); 00122 outputter.pushFieldSpec("num loops", TO::INT); 00123 outputter.pushFieldSpec("raw ptr", TO::DOUBLE); 00124 outputter.pushFieldSpec("vector", TO::DOUBLE); 00125 outputter.pushFieldSpec("Array", TO::DOUBLE); 00126 outputter.pushFieldSpec("vector/raw", TO::DOUBLE); 00127 outputter.pushFieldSpec("Array/raw", TO::DOUBLE); 00128 00129 outputter.outputHeader(); 00130 00131 // Start out really big to make sure it fails if not set correctly! 00132 double finalArrayBraketRatio = 100000.0; 00133 00134 Ordinal arraySize = minArraySize; 00135 for (int test_case_k = 0; 00136 test_case_k < maxLoopIters && arraySize <= maxArraySize; 00137 ++test_case_k 00138 ) 00139 { 00140 00141 // array dim 00142 outputter.outputField(arraySize); 00143 00144 // num loops 00145 const int numActualLoops = 00146 TEUCHOS_MAX( 00147 static_cast<int>( 00148 (numInnerLoops / arraySize) 00149 * std::log(static_cast<double>(arraySize+1)) 00150 ), 00151 1 00152 ); 00153 outputter.outputField(numActualLoops); 00154 00155 std::vector<double> vec(arraySize); 00156 00157 // raw ptr 00158 { 00159 double *p_raw = &vec[0]; 00160 TEUCHOS_START_PERF_OUTPUT_TIMER_INNERLOOP(outputter, numActualLoops, arraySize) 00161 { 00162 for (Ordinal i=0; i < arraySize; ++i) 00163 p_raw[i] = 0.0; 00164 } 00165 } 00166 TEUCHOS_END_PERF_OUTPUT_TIMER(outputter, rawPtrTime); 00167 00168 // vector 00169 TEUCHOS_START_PERF_OUTPUT_TIMER_INNERLOOP(outputter, numActualLoops, arraySize) 00170 { 00171 for (Ordinal i=0; i < arraySize; ++i) 00172 vec[i] = 0.0; 00173 } 00174 TEUCHOS_END_PERF_OUTPUT_TIMER(outputter, vectorTime); 00175 00176 // Array 00177 { 00178 Teuchos::Array<double> a(arraySize); 00179 TEUCHOS_START_PERF_OUTPUT_TIMER_INNERLOOP(outputter, numActualLoops, arraySize) 00180 { 00181 for (Ordinal i=0; i < arraySize; ++i) 00182 a[i] = 0.0; 00183 } 00184 } 00185 TEUCHOS_END_PERF_OUTPUT_TIMER(outputter, arrayTime); 00186 00187 // vector/raw 00188 const double vectorRatio = vectorTime / rawPtrTime; 00189 outputter.outputField(vectorRatio); 00190 00191 // Array/raw 00192 const double arrayRatio = arrayTime / rawPtrTime; 00193 outputter.outputField(arrayRatio); 00194 00195 outputter.nextRow(); 00196 00197 arraySize *= 4; 00198 finalArrayBraketRatio = TEUCHOS_MIN(arrayRatio, finalArrayBraketRatio); 00199 00200 } 00201 00202 out << "\n"; 00203 TEST_COMPARE( finalArrayBraketRatio, <=, maxArrayBracketRatio ); 00204 out << "\n"; 00205 00206 } 00207 00208 00209 TEUCHOS_UNIT_TEST( ArrayView, braketOperatorOverhead ) 00210 { 00211 00212 typedef Teuchos::TabularOutputter TO; 00213 00214 const double relTestCost = 1e-4; 00215 00216 const double numInnerLoops = relCpuSpeed / relTestCost; 00217 00218 out << "\n" 00219 << "Measuring the overhead of the ArrayView braket operator relative to raw pointers.\n" 00220 << "\n" 00221 << "Number of loops = relCpuSpeed/relTestCost = " 00222 << relCpuSpeed << "/" << relTestCost << " = " << numInnerLoops << "\n" 00223 << "\n"; 00224 00225 TabularOutputter outputter(out); 00226 outputter.setFieldTypePrecision(TO::DOUBLE, dblPrec); 00227 outputter.setFieldTypePrecision(TO::INT, intPrec); 00228 00229 outputter.pushFieldSpec("array dim", TO::INT); 00230 outputter.pushFieldSpec("num loops", TO::INT); 00231 outputter.pushFieldSpec("raw ptr", TO::DOUBLE); 00232 outputter.pushFieldSpec("ArrayView", TO::DOUBLE); 00233 outputter.pushFieldSpec("ArrayView/raw", TO::DOUBLE); 00234 00235 outputter.outputHeader(); 00236 00237 // Start out really big to make sure it fails if not set correctly! 00238 double finalArrayViewBraketRatio = 100000.0; 00239 00240 Ordinal arraySize = minArraySize; 00241 for (int test_case_k = 0; 00242 test_case_k < maxLoopIters && arraySize <= maxArraySize; 00243 ++test_case_k 00244 ) 00245 { 00246 00247 // array dim 00248 outputter.outputField(arraySize); 00249 00250 // num loops 00251 const int numActualLoops = 00252 TEUCHOS_MAX( 00253 static_cast<int>( 00254 (numInnerLoops / arraySize) 00255 * std::log(static_cast<double>(arraySize+1)) 00256 ), 00257 1 00258 ); 00259 outputter.outputField(numActualLoops); 00260 00261 std::vector<double> vec(arraySize); 00262 00263 // raw ptr 00264 double *p_raw = &vec[0]; 00265 TEUCHOS_START_PERF_OUTPUT_TIMER_INNERLOOP(outputter, numActualLoops, arraySize) 00266 { 00267 for (Ordinal i=0; i < arraySize; ++i) 00268 p_raw[i] = 0.0; 00269 } 00270 TEUCHOS_END_PERF_OUTPUT_TIMER(outputter, rawPtrTime); 00271 00272 // ArrayView 00273 Teuchos::Array<double> a(arraySize); 00274 Teuchos::ArrayView<double> av = a; 00275 TEUCHOS_START_PERF_OUTPUT_TIMER_INNERLOOP(outputter, numActualLoops, arraySize) 00276 { 00277 for (Ordinal i=0; i < arraySize; ++i) 00278 av[i] = 0.0; 00279 } 00280 TEUCHOS_END_PERF_OUTPUT_TIMER(outputter, arrayviewTime); 00281 00282 // Array/raw 00283 const double arrayviewRatio = arrayviewTime / rawPtrTime; 00284 outputter.outputField(arrayviewRatio); 00285 00286 outputter.nextRow(); 00287 00288 arraySize *= 4; 00289 finalArrayViewBraketRatio = TEUCHOS_MIN(arrayviewRatio, finalArrayViewBraketRatio); 00290 00291 } 00292 00293 out << "\n"; 00294 TEST_COMPARE( finalArrayViewBraketRatio, <=, maxArrayBracketRatio ); 00295 out << "\n"; 00296 00297 } 00298 00299 00300 TEUCHOS_UNIT_TEST( ArrayRCP, braketOperatorOverhead ) 00301 { 00302 00303 typedef Teuchos::TabularOutputter TO; 00304 00305 const double relTestCost = 1e-4; 00306 00307 const double numInnerLoops = relCpuSpeed / relTestCost; 00308 00309 out << "\n" 00310 << "Measuring the overhead of the ArrayRCP braket operator relative to raw pointers.\n" 00311 << "\n" 00312 << "Number of loops = relCpuSpeed/relTestCost = " 00313 << relCpuSpeed << "/" << relTestCost << " = " << numInnerLoops << "\n" 00314 << "\n"; 00315 00316 TabularOutputter outputter(out); 00317 outputter.setFieldTypePrecision(TO::DOUBLE, dblPrec); 00318 outputter.setFieldTypePrecision(TO::INT, intPrec); 00319 00320 outputter.pushFieldSpec("array dim", TO::INT); 00321 outputter.pushFieldSpec("num loops", TO::INT); 00322 outputter.pushFieldSpec("raw ptr", TO::DOUBLE); 00323 outputter.pushFieldSpec("ArrayRCP", TO::DOUBLE); 00324 outputter.pushFieldSpec("ArrayRCP/raw", TO::DOUBLE); 00325 00326 outputter.outputHeader(); 00327 00328 // Start out really big to make sure it fails if not set correctly! 00329 double finalArrayRCPBraketRatio = 100000.0; 00330 00331 Ordinal arraySize = minArraySize; 00332 for (int test_case_k = 0; 00333 test_case_k < maxLoopIters && arraySize <= maxArraySize; 00334 ++test_case_k 00335 ) 00336 { 00337 00338 // array dim 00339 outputter.outputField(arraySize); 00340 00341 // num loops 00342 const int numActualLoops = 00343 TEUCHOS_MAX( 00344 static_cast<int>( 00345 (numInnerLoops / arraySize) 00346 * std::log(static_cast<double>(arraySize+1)) 00347 ), 00348 1 00349 ); 00350 outputter.outputField(numActualLoops); 00351 00352 std::vector<double> vec(arraySize); 00353 00354 // raw ptr 00355 double *p_raw = &vec[0]; 00356 TEUCHOS_START_PERF_OUTPUT_TIMER_INNERLOOP(outputter, numActualLoops, arraySize) 00357 { 00358 for (Ordinal i=0; i < arraySize; ++i) 00359 p_raw[i] = 0.0; 00360 } 00361 TEUCHOS_END_PERF_OUTPUT_TIMER(outputter, rawPtrTime); 00362 00363 // ArrayRCP 00364 Teuchos::ArrayRCP<double> arcp = Teuchos::arcp<double>(arraySize); 00365 TEUCHOS_START_PERF_OUTPUT_TIMER_INNERLOOP(outputter, numActualLoops, arraySize) 00366 { 00367 for (Ordinal i=0; i < arraySize; ++i) 00368 arcp[i] = 0.0; 00369 } 00370 TEUCHOS_END_PERF_OUTPUT_TIMER(outputter, arrayrcpTime); 00371 00372 // Array/raw 00373 const double arrayrcpRatio = arrayrcpTime / rawPtrTime; 00374 outputter.outputField(arrayrcpRatio); 00375 00376 outputter.nextRow(); 00377 00378 arraySize *= 4; 00379 finalArrayRCPBraketRatio = TEUCHOS_MIN(arrayrcpRatio, finalArrayRCPBraketRatio); 00380 00381 } 00382 00383 out << "\n"; 00384 TEST_COMPARE( finalArrayRCPBraketRatio, <=, maxArrayBracketRatio ); 00385 out << "\n"; 00386 00387 } 00388 00389 00390 TEUCHOS_UNIT_TEST( Array, iteratorOverhead ) 00391 { 00392 00393 typedef Teuchos::TabularOutputter TO; 00394 00395 const double relTestCost = 1e-4; 00396 00397 const double numInnerLoops = relCpuSpeed / relTestCost; 00398 00399 out << "\n" 00400 << "Measuring the overhead of the Array iterators relative to raw pointers.\n" 00401 << "\n" 00402 << "Number of loops = relCpuSpeed/relTestCost = " 00403 << relCpuSpeed << "/" << relTestCost << " = " << numInnerLoops << "\n" 00404 << "\n"; 00405 00406 TabularOutputter outputter(out); 00407 outputter.setFieldTypePrecision(TO::DOUBLE, dblPrec); 00408 outputter.setFieldTypePrecision(TO::INT, intPrec); 00409 00410 outputter.pushFieldSpec("array dim", TO::INT); 00411 outputter.pushFieldSpec("num loops", TO::INT); 00412 outputter.pushFieldSpec("raw ptr", TO::DOUBLE); 00413 outputter.pushFieldSpec("vector", TO::DOUBLE); 00414 outputter.pushFieldSpec("Array", TO::DOUBLE); 00415 outputter.pushFieldSpec("vector/raw", TO::DOUBLE); 00416 outputter.pushFieldSpec("Array/raw", TO::DOUBLE); 00417 00418 outputter.outputHeader(); 00419 00420 // Start out really big to make sure it fails if not set correctly! 00421 double finalArrayIterRatio = 100000.0; 00422 00423 Ordinal arraySize = minArraySize; 00424 for (int test_case_k = 0; 00425 test_case_k < maxLoopIters && arraySize <= maxArraySize; 00426 ++test_case_k 00427 ) 00428 { 00429 00430 // array dim 00431 outputter.outputField(arraySize); 00432 00433 // num loops 00434 const int numActualLoops = 00435 TEUCHOS_MAX( 00436 static_cast<int>( 00437 (numInnerLoops / arraySize) 00438 * std::log(static_cast<double>(arraySize+1)) 00439 ), 00440 1 00441 ); 00442 outputter.outputField(numActualLoops); 00443 00444 std::vector<double> vec(arraySize); 00445 00446 // raw ptr 00447 TEUCHOS_START_PERF_OUTPUT_TIMER_INNERLOOP(outputter, numActualLoops, arraySize) 00448 { 00449 double 00450 *p_raw_itr = &vec[0], 00451 *p_raw_end = &vec[0] + arraySize; 00452 for ( ; p_raw_itr < p_raw_end; ++p_raw_itr) 00453 *p_raw_itr = 0.0; 00454 } 00455 TEUCHOS_END_PERF_OUTPUT_TIMER(outputter, rawPtrTime); 00456 00457 // vector 00458 TEUCHOS_START_PERF_OUTPUT_TIMER_INNERLOOP(outputter, numActualLoops, arraySize) 00459 { 00460 std::vector<double>::iterator 00461 vec_itr = vec.begin(), 00462 vec_end = vec.end(); 00463 for ( ; vec_itr < vec_end; ++vec_itr) 00464 *vec_itr = 0.0; 00465 } 00466 TEUCHOS_END_PERF_OUTPUT_TIMER(outputter, vectorTime); 00467 00468 // Array 00469 Teuchos::Array<double> a(arraySize); 00470 TEUCHOS_START_PERF_OUTPUT_TIMER_INNERLOOP(outputter, numActualLoops, arraySize) 00471 { 00472 Teuchos::Array<double>::iterator 00473 a_itr = a.begin(), 00474 a_end = a.end(); 00475 for ( ; a_itr < a_end; ++a_itr) 00476 *a_itr = 0.0; 00477 } 00478 TEUCHOS_END_PERF_OUTPUT_TIMER(outputter, arrayTime); 00479 00480 // vector/raw 00481 const double vectorRatio = vectorTime / rawPtrTime; 00482 outputter.outputField(vectorRatio); 00483 00484 // Array/raw 00485 const double arrayRatio = arrayTime / rawPtrTime; 00486 outputter.outputField(arrayRatio); 00487 00488 outputter.nextRow(); 00489 00490 arraySize *= 4; 00491 finalArrayIterRatio = TEUCHOS_MIN(arrayRatio, finalArrayIterRatio); 00492 00493 } 00494 00495 out << "\n"; 00496 TEST_COMPARE( finalArrayIterRatio, <=, maxArrayIterRatio ); 00497 out << "\n"; 00498 00499 } 00500 00501 00502 TEUCHOS_UNIT_TEST( ArrayView, iteratorOverhead ) 00503 { 00504 00505 typedef Teuchos::TabularOutputter TO; 00506 00507 const double relTestCost = 1e-4; 00508 00509 const double numInnerLoops = relCpuSpeed / relTestCost; 00510 00511 out << "\n" 00512 << "Measuring the overhead of the ArrayView iterators relative to raw pointers.\n" 00513 << "\n" 00514 << "Number of loops = relCpuSpeed/relTestCost = " 00515 << relCpuSpeed << "/" << relTestCost << " = " << numInnerLoops << "\n" 00516 << "\n"; 00517 00518 TabularOutputter outputter(out); 00519 outputter.setFieldTypePrecision(TO::DOUBLE, dblPrec); 00520 outputter.setFieldTypePrecision(TO::INT, intPrec); 00521 00522 outputter.pushFieldSpec("array dim", TO::INT); 00523 outputter.pushFieldSpec("num loops", TO::INT); 00524 outputter.pushFieldSpec("raw ptr", TO::DOUBLE); 00525 outputter.pushFieldSpec("ArrayView", TO::DOUBLE); 00526 outputter.pushFieldSpec("ArrayView/raw", TO::DOUBLE); 00527 00528 outputter.outputHeader(); 00529 00530 // Start out really big to make sure it fails if not set correctly! 00531 double finalArrayViewIterRatio = 100000.0; 00532 00533 Ordinal arraySize = minArraySize; 00534 for (int test_case_k = 0; 00535 test_case_k < maxLoopIters && arraySize <= maxArraySize; 00536 ++test_case_k 00537 ) 00538 { 00539 00540 // array dim 00541 outputter.outputField(arraySize); 00542 00543 // num loops 00544 const int numActualLoops = 00545 TEUCHOS_MAX( 00546 static_cast<int>( 00547 (numInnerLoops / arraySize) 00548 * std::log(static_cast<double>(arraySize+1)) 00549 ), 00550 1 00551 ); 00552 outputter.outputField(numActualLoops); 00553 00554 std::vector<double> vec(arraySize); 00555 00556 // raw ptr 00557 TEUCHOS_START_PERF_OUTPUT_TIMER_INNERLOOP(outputter, numActualLoops, arraySize) 00558 { 00559 double 00560 *p_raw_itr = &vec[0], 00561 *p_raw_end = &vec[0] + arraySize; 00562 for ( ; p_raw_itr < p_raw_end; ++p_raw_itr) 00563 *p_raw_itr = 0.0; 00564 } 00565 TEUCHOS_END_PERF_OUTPUT_TIMER(outputter, rawPtrTime); 00566 00567 // ArrayView 00568 Teuchos::Array<double> a(arraySize); 00569 Teuchos::ArrayView<double> av = a; 00570 TEUCHOS_START_PERF_OUTPUT_TIMER_INNERLOOP(outputter, numActualLoops, arraySize) 00571 { 00572 Teuchos::ArrayView<double>::iterator 00573 av_itr = av.begin(), 00574 av_end = av.end(); 00575 for ( ; av_itr < av_end ; ++av_itr) 00576 *av_itr = 0.0; 00577 } 00578 TEUCHOS_END_PERF_OUTPUT_TIMER(outputter, arrayviewTime); 00579 00580 // ArrayView/raw 00581 const double arrayviewRatio = arrayviewTime / rawPtrTime; 00582 outputter.outputField(arrayviewRatio); 00583 00584 outputter.nextRow(); 00585 00586 arraySize *= 4; 00587 finalArrayViewIterRatio = TEUCHOS_MIN(arrayviewRatio, finalArrayViewIterRatio); 00588 00589 } 00590 00591 out << "\n"; 00592 TEST_COMPARE( finalArrayViewIterRatio, <=, maxArrayIterRatio ); 00593 out << "\n"; 00594 00595 } 00596 00597 00598 TEUCHOS_UNIT_TEST( ArrayRCP, iteratorOverhead ) 00599 { 00600 00601 typedef Teuchos::TabularOutputter TO; 00602 00603 const double relTestCost = 1e-4; 00604 00605 const double numInnerLoops = relCpuSpeed / relTestCost; 00606 00607 out << "\n" 00608 << "Measuring the overhead of the ArrayRCP iterators relative to raw pointers.\n" 00609 << "\n" 00610 << "Number of loops = relCpuSpeed/relTestCost = " 00611 << relCpuSpeed << "/" << relTestCost << " = " << numInnerLoops << "\n" 00612 << "\n"; 00613 00614 TabularOutputter outputter(out); 00615 outputter.setFieldTypePrecision(TO::DOUBLE, dblPrec); 00616 outputter.setFieldTypePrecision(TO::INT, intPrec); 00617 00618 outputter.pushFieldSpec("array dim", TO::INT); 00619 outputter.pushFieldSpec("num loops", TO::INT); 00620 outputter.pushFieldSpec("raw ptr", TO::DOUBLE); 00621 outputter.pushFieldSpec("ArrayRCP", TO::DOUBLE); 00622 outputter.pushFieldSpec("ArrayRCP/raw", TO::DOUBLE); 00623 00624 outputter.outputHeader(); 00625 00626 // Start out really big to make sure it fails if not set correctly! 00627 double finalArrayRCPIterRatio = 100000.0; 00628 00629 Ordinal arraySize = minArraySize; 00630 for (int test_case_k = 0; 00631 test_case_k < maxLoopIters && arraySize <= maxArraySize; 00632 ++test_case_k 00633 ) 00634 { 00635 00636 // array dim 00637 outputter.outputField(arraySize); 00638 00639 // num loops 00640 const int numActualLoops = 00641 TEUCHOS_MAX( 00642 static_cast<int>( 00643 (numInnerLoops / arraySize) 00644 * std::log(static_cast<double>(arraySize+1)) 00645 ), 00646 1 00647 ); 00648 outputter.outputField(numActualLoops); 00649 00650 std::vector<double> vec(arraySize); 00651 00652 // raw ptr 00653 TEUCHOS_START_PERF_OUTPUT_TIMER_INNERLOOP(outputter, numActualLoops, arraySize) 00654 { 00655 double 00656 *p_raw_itr = &vec[0], 00657 *p_raw_end = &vec[0] + arraySize; 00658 for ( ; p_raw_itr < p_raw_end; ++p_raw_itr) 00659 *p_raw_itr = 0.0; 00660 } 00661 TEUCHOS_END_PERF_OUTPUT_TIMER(outputter, rawPtrTime); 00662 00663 // ArrayRCP 00664 Teuchos::ArrayRCP<double> ap = Teuchos::arcp<double>(arraySize); 00665 TEUCHOS_START_PERF_OUTPUT_TIMER_INNERLOOP(outputter, numActualLoops, arraySize) 00666 { 00667 Teuchos::ArrayRCP<double>::iterator 00668 ap_itr = ap.begin(), 00669 ap_end = ap.end(); 00670 for ( ; ap_itr < ap_end; ++ap_itr) 00671 *ap_itr = 0.0; 00672 } 00673 TEUCHOS_END_PERF_OUTPUT_TIMER(outputter, arrayviewTime); 00674 00675 // ArrayRCP/raw 00676 const double arrayviewRatio = arrayviewTime / rawPtrTime; 00677 outputter.outputField(arrayviewRatio); 00678 00679 outputter.nextRow(); 00680 00681 arraySize *= 4; 00682 finalArrayRCPIterRatio = TEUCHOS_MIN(arrayviewRatio, finalArrayRCPIterRatio); 00683 00684 } 00685 00686 out << "\n"; 00687 TEST_COMPARE( finalArrayRCPIterRatio, <=, maxArrayIterRatio ); 00688 out << "\n"; 00689 00690 } 00691 00692 00693 TEUCHOS_UNIT_TEST( ArrayRCP, selfIteratorOverhead ) 00694 { 00695 00696 typedef Teuchos::TabularOutputter TO; 00697 00698 const double relTestCost = 1e-4; 00699 00700 const double numInnerLoops = relCpuSpeed / relTestCost; 00701 00702 out << "\n" 00703 << "Measuring the overhead of the ArrayRCP as a self iterataor relative to raw pointers.\n" 00704 << "\n" 00705 << "Number of loops = relCpuSpeed/relTestCost = " 00706 << relCpuSpeed << "/" << relTestCost << " = " << numInnerLoops << "\n" 00707 << "\n"; 00708 00709 TabularOutputter outputter(out); 00710 outputter.setFieldTypePrecision(TO::DOUBLE, dblPrec); 00711 outputter.setFieldTypePrecision(TO::INT, intPrec); 00712 00713 outputter.pushFieldSpec("array dim", TO::INT); 00714 outputter.pushFieldSpec("num loops", TO::INT); 00715 outputter.pushFieldSpec("raw ptr", TO::DOUBLE); 00716 outputter.pushFieldSpec("ArrayRCP", TO::DOUBLE); 00717 outputter.pushFieldSpec("ArrayRCP/raw", TO::DOUBLE); 00718 00719 outputter.outputHeader(); 00720 00721 // Start out really big to make sure it fails if not set correctly! 00722 double finalArrayRCPIterRatio = 100000.0; 00723 00724 Ordinal arraySize = minArraySize; 00725 for (int test_case_k = 0; 00726 test_case_k < maxLoopIters && arraySize <= maxArraySize; 00727 ++test_case_k 00728 ) 00729 { 00730 00731 // array dim 00732 outputter.outputField(arraySize); 00733 00734 // num loops 00735 const int numActualLoops = 00736 TEUCHOS_MAX( 00737 static_cast<int>( 00738 (numInnerLoops / arraySize) 00739 * std::log(static_cast<double>(arraySize+1)) 00740 ), 00741 1 00742 ); 00743 outputter.outputField(numActualLoops); 00744 00745 std::vector<double> vec(arraySize); 00746 00747 // raw ptr 00748 TEUCHOS_START_PERF_OUTPUT_TIMER_INNERLOOP(outputter, numActualLoops, arraySize) 00749 { 00750 double 00751 *p_raw_itr = &vec[0], 00752 *p_raw_end = &vec[0] + arraySize; 00753 for ( ; p_raw_itr < p_raw_end; ++p_raw_itr) 00754 *p_raw_itr = 0.0; 00755 } 00756 TEUCHOS_END_PERF_OUTPUT_TIMER(outputter, rawPtrTime); 00757 00758 // ArrayRCP 00759 Teuchos::ArrayRCP<double> ap = Teuchos::arcp<double>(arraySize); 00760 TEUCHOS_START_PERF_OUTPUT_TIMER_INNERLOOP(outputter, numActualLoops, arraySize) 00761 { 00762 Teuchos::ArrayRCP<double> 00763 ap_itr = ap, 00764 ap_end = ap + arraySize; 00765 for ( ; ap_itr < ap_end; ++ap_itr) 00766 *ap_itr = 0.0; 00767 } 00768 TEUCHOS_END_PERF_OUTPUT_TIMER(outputter, arrayviewTime); 00769 00770 // ArrayRCP/raw 00771 const double arrayviewRatio = arrayviewTime / rawPtrTime; 00772 outputter.outputField(arrayviewRatio); 00773 00774 outputter.nextRow(); 00775 00776 arraySize *= 4; 00777 finalArrayRCPIterRatio = TEUCHOS_MIN(arrayviewRatio, finalArrayRCPIterRatio); 00778 00779 } 00780 00781 out << "\n"; 00782 TEST_COMPARE( finalArrayRCPIterRatio, <=, maxArrayRCPSelfIterRatio ); 00783 out << "\n"; 00784 00785 } 00786 00787 00788 } // namespace
1.7.6.1