Teuchos Package Browser (Single Doxygen Collection) Version of the Day
Array_Performance_UnitTests.cpp
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines