Array_Performance_UnitTests.cpp

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