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 // 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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines