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