|
Teuchos Package Browser (Single Doxygen Collection)
Version of the Day
|
00001 /* 00002 // @HEADER 00003 // *********************************************************************** 00004 // 00005 // Teuchos: Common Tools Package 00006 // Copyright (2004) Sandia Corporation 00007 // 00008 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive 00009 // license for use of this work by or on behalf of the U.S. Government. 00010 // 00011 // Redistribution and use in source and binary forms, with or without 00012 // modification, are permitted provided that the following conditions are 00013 // met: 00014 // 00015 // 1. Redistributions of source code must retain the above copyright 00016 // notice, this list of conditions and the following disclaimer. 00017 // 00018 // 2. Redistributions in binary form must reproduce the above copyright 00019 // notice, this list of conditions and the following disclaimer in the 00020 // documentation and/or other materials provided with the distribution. 00021 // 00022 // 3. Neither the name of the Corporation nor the names of the 00023 // contributors may be used to endorse or promote products derived from 00024 // this software without specific prior written permission. 00025 // 00026 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY 00027 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00028 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 00029 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE 00030 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00031 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00032 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00033 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00034 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00035 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00036 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00037 // 00038 // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 00039 // 00040 // *********************************************************************** 00041 // @HEADER 00042 */ 00043 00044 #include "Teuchos_UnitTestHarness.hpp" 00045 #include "Teuchos_RCP.hpp" 00046 #include "Teuchos_TabularOutputter.hpp" 00047 00048 #ifdef HAVE_TEUCHOS_BOOST 00049 # include "boost/shared_ptr.hpp" 00050 #endif 00051 00052 00053 namespace { 00054 00055 00056 using Teuchos::null; 00057 using Teuchos::RCP; 00058 using Teuchos::rcp; 00059 using Teuchos::TabularOutputter; 00060 00061 00062 double relCpuSpeed = 1e-2; 00063 int maxArraySize = 10000; 00064 double maxRcpRawCreateDestroyRatio = 10.0; 00065 double maxRcpRawAdjustRefCountRatio = 100.0; 00066 double maxRcpSpAdjustRefCountRatio = 5.0; 00067 double maxRcpRawObjAccessRatio = 10.0; 00068 00069 const int intPrec = 8; 00070 const int dblPrec = 6; 00071 00072 00073 TEUCHOS_STATIC_SETUP() 00074 { 00075 Teuchos::CommandLineProcessor &clp = 00076 Teuchos::UnitTestRepository::getCLP(); 00077 clp.setOption( 00078 "rel-cpu-speed", &relCpuSpeed, 00079 "The relative speed of the CPU (higher means the machine runs faster)" 00080 ); 00081 clp.setOption( 00082 "max-array-size", &maxArraySize, 00083 "The maximum size of the arrays created" 00084 ); 00085 clp.setOption( 00086 "max-rcp-create-destroy-ratio", &maxRcpRawCreateDestroyRatio, 00087 "The ratio of the final CPU time ratio of creating and destroying" 00088 "std::vector<char>(size) objects wrapped in an RCP object versus" 00089 "using just raw new and delete." 00090 ); 00091 clp.setOption( 00092 "max-rcp-raw-adjust-ref-count-ratio", &maxRcpRawAdjustRefCountRatio, 00093 "The ratio of the final CPU time ratio for adjusting the reference" 00094 "count of RCP objects versus a raw pointer." 00095 ); 00096 clp.setOption( 00097 "max-rcp-sp-adjust-ref-count-ratio", &maxRcpSpAdjustRefCountRatio, 00098 "The ratio of the final CPU time ratio for adjusting the reference" 00099 "count of RCP objects versus boost::shared_ptr objects." 00100 ); 00101 clp.setOption( 00102 "max-rcp-raw-obj-access-ratio", &maxRcpRawObjAccessRatio, 00103 "The ratio of the final CPU time ratio for accessing the object for RCP" 00104 "versus a raw pointer." 00105 ); 00106 00107 } 00108 00109 00110 template<typename T> 00111 struct DeleteDeleter {}; 00112 00113 00114 TEUCHOS_UNIT_TEST( RCP, _sizeofObjects ) 00115 { 00116 out << "\nPrinting the size the RCP and RCPNodeImpl objects ...\n"; 00117 TEST_INEQUALITY_CONST(sizeof(bool), 0); 00118 TEST_INEQUALITY_CONST(sizeof(double), 0); 00119 TEST_INEQUALITY_CONST(sizeof(double*), 0); 00120 TEST_INEQUALITY_CONST(sizeof(std::vector<double>), 0); 00121 TEST_INEQUALITY_CONST(sizeof(Teuchos::RCPNode*), 0); 00122 TEST_INEQUALITY_CONST(sizeof(Teuchos::ERCPStrength), 0); 00123 TEST_INEQUALITY_CONST(sizeof(Teuchos::RCPNodeHandle), 0); 00124 TEST_INEQUALITY_CONST(sizeof(Teuchos::RCP<std::vector<double> >), 0); 00125 TEST_INEQUALITY_CONST( 00126 sizeof(Teuchos::RCPNodeTmpl<std::vector<double>, 00127 Teuchos::DeallocDelete<std::vector<double> > >), 00128 0); 00129 #ifdef HAVE_TEUCHOS_BOOST 00130 TEST_INEQUALITY_CONST(sizeof(boost::detail::shared_count), 0); 00131 TEST_INEQUALITY_CONST(sizeof(boost::shared_ptr<std::vector<double> >), 0); 00132 TEST_INEQUALITY_CONST(sizeof(boost::detail::sp_counted_impl_p<std::vector<double> >), 0); 00133 TEST_INEQUALITY_CONST( 00134 sizeof(boost::detail::sp_counted_impl_pd<std::vector<double>, 00135 DeleteDeleter<std::vector<double> > >), 00136 0); 00137 #endif 00138 } 00139 00140 00141 TEUCHOS_UNIT_TEST( RCP, createDestroyOverhead ) 00142 { 00143 00144 typedef Teuchos::TabularOutputter TO; 00145 00146 const int maxLoopIters = 1000; 00147 const double relTestCost = 1e-3; 00148 const double numInnerLoops = relCpuSpeed / relTestCost; 00149 00150 out << "\n" 00151 << "Messuring the overhead of creating and destorying objects of different sizes\n" 00152 << "using raw C++ pointers, shared_ptr, and using RCP.\n" 00153 << "\n" 00154 << "Number of loops = relCpuSpeed/relTestCost = " 00155 << relCpuSpeed << "/" << relTestCost << " = " << numInnerLoops << "\n" 00156 << "\n"; 00157 00158 TabularOutputter outputter(out); 00159 outputter.setFieldTypePrecision(TO::DOUBLE, dblPrec); 00160 outputter.setFieldTypePrecision(TO::INT, intPrec); 00161 00162 outputter.pushFieldSpec("obj size", TO::INT); 00163 outputter.pushFieldSpec("num loops", TO::INT); 00164 outputter.pushFieldSpec("raw", TO::DOUBLE); 00165 #ifdef HAVE_TEUCHOS_BOOST 00166 outputter.pushFieldSpec("shared_ptr", TO::DOUBLE); 00167 #endif 00168 outputter.pushFieldSpec("RCP", TO::DOUBLE); 00169 #ifdef HAVE_TEUCHOS_BOOST 00170 outputter.pushFieldSpec("shared_ptr/raw", TO::DOUBLE); 00171 #endif 00172 outputter.pushFieldSpec("RCP/raw", TO::DOUBLE); 00173 00174 outputter.outputHeader(); 00175 00176 double finalRcpRawRatio = 100000.0; 00177 00178 int arraySize = 1; 00179 for (int test_case_k = 0; 00180 test_case_k < maxLoopIters && arraySize <= maxArraySize; 00181 ++test_case_k 00182 ) 00183 { 00184 00185 // obj size 00186 outputter.outputField(arraySize); 00187 00188 // num loops 00189 const int numActualLoops = 00190 TEUCHOS_MAX( 00191 static_cast<int>( 00192 (numInnerLoops / arraySize) 00193 * std::log(static_cast<double>(arraySize+1)) 00194 ), 00195 1 00196 ); 00197 outputter.outputField(numActualLoops); 00198 00199 // raw 00200 { 00201 std::vector<std::vector<char>*> p_raw_vec(numActualLoops); 00202 int i = 0; 00203 TEUCHOS_START_PERF_OUTPUT_TIMER(outputter, numActualLoops) 00204 { 00205 p_raw_vec[i] = new std::vector<char>(arraySize, 1); 00206 delete p_raw_vec[i]; 00207 ++i; 00208 } 00209 } 00210 TEUCHOS_END_PERF_OUTPUT_TIMER(outputter, rawPtrTime); 00211 00212 #ifdef HAVE_TEUCHOS_BOOST 00213 // shared_ptr 00214 { 00215 typedef boost::shared_ptr<std::vector<char> > shared_ptr_t; 00216 std::vector<shared_ptr_t > sp_vec(numActualLoops); 00217 int i = 0; 00218 TEUCHOS_START_PERF_OUTPUT_TIMER(outputter, numActualLoops) 00219 { 00220 sp_vec[i] = shared_ptr_t(new std::vector<char>(arraySize, 1)); 00221 sp_vec[i].reset(); 00222 ++i; 00223 } 00224 } 00225 TEUCHOS_END_PERF_OUTPUT_TIMER(outputter, spTime); 00226 #endif 00227 00228 // RCP 00229 { 00230 std::vector<RCP<std::vector<char> > > p_vec(numActualLoops); 00231 int i = 0; 00232 TEUCHOS_START_PERF_OUTPUT_TIMER(outputter, numActualLoops) 00233 { 00234 p_vec[i] = rcp(new std::vector<char>(arraySize, 1)); 00235 p_vec[i] = null; 00236 } 00237 } 00238 TEUCHOS_END_PERF_OUTPUT_TIMER(outputter, rcpTime); 00239 00240 #ifdef HAVE_TEUCHOS_BOOST 00241 // shared_ptr/rawPtr 00242 const double spRatio = spTime / rawPtrTime; 00243 outputter.outputField(spRatio); 00244 #endif 00245 00246 // RCP/rawPtr 00247 const double rcpRatio = rcpTime / rawPtrTime; 00248 outputter.outputField(rcpRatio); 00249 00250 outputter.nextRow(); 00251 00252 arraySize *= 4; 00253 finalRcpRawRatio = TEUCHOS_MIN(rcpRatio, finalRcpRawRatio); 00254 00255 } 00256 00257 out << "\n"; 00258 TEST_COMPARE( finalRcpRawRatio, <=, maxRcpRawCreateDestroyRatio ); 00259 out << "\n"; 00260 00261 } 00262 00263 00264 TEUCHOS_UNIT_TEST( RCP, referenceCountManipulationOverhead ) 00265 { 00266 00267 typedef Teuchos::TabularOutputter TO; 00268 00269 const double relTestCost = 5e-3; 00270 const int maxLoopIters = 1000; 00271 const double numInnerLoops = relCpuSpeed / relTestCost; 00272 00273 out << "\n" 00274 << "Messuring the overhead of incrementing and deincrementing the reference count\n" 00275 << "comparing RCP to raw pointer and boost::shared_ptr.\n" 00276 << "\n"; 00277 00278 TabularOutputter outputter(out); 00279 outputter.setFieldTypePrecision(TO::DOUBLE, dblPrec); 00280 outputter.setFieldTypePrecision(TO::INT, intPrec); 00281 00282 outputter.pushFieldSpec("array dim", TO::INT); 00283 outputter.pushFieldSpec("num loops", TO::INT); 00284 outputter.pushFieldSpec("raw", TO::DOUBLE); 00285 outputter.pushFieldSpec("shared_ptr", TO::DOUBLE); 00286 outputter.pushFieldSpec("RCP", TO::DOUBLE); 00287 outputter.pushFieldSpec("RCP/raw", TO::DOUBLE); 00288 outputter.pushFieldSpec("RCP/shared_ptr", TO::DOUBLE); 00289 00290 outputter.outputHeader(); 00291 00292 double finalRcpRawRatio = 100000.0; 00293 double finalRcpSpRatio = 100000.0; 00294 int arraySize = 64; 00295 00296 for ( 00297 int test_case_k = 0; 00298 test_case_k < maxLoopIters && arraySize <= maxArraySize; 00299 ++test_case_k 00300 ) 00301 { 00302 00303 // array dim 00304 outputter.outputField(arraySize); 00305 00306 // num loops 00307 const int numActualLoops = 00308 TEUCHOS_MAX( 00309 static_cast<int>( 00310 (numInnerLoops / arraySize) 00311 * std::log(static_cast<double>(arraySize+1)) 00312 ), 00313 1 00314 ); 00315 outputter.outputField(numActualLoops); 00316 00317 // raw 00318 { 00319 char dummy_char = 'n'; 00320 std::vector<char*> p_raw_vec(arraySize); 00321 TEUCHOS_START_PERF_OUTPUT_TIMER_INNERLOOP(outputter, numActualLoops, arraySize) 00322 { 00323 for (int i=0; i < arraySize; ++i) { 00324 p_raw_vec[i] = &dummy_char; 00325 } 00326 } 00327 } 00328 TEUCHOS_END_PERF_OUTPUT_TIMER(outputter, rawPtrTime); 00329 00330 #ifdef HAVE_TEUCHOS_BOOST 00331 // shared_ptr 00332 { 00333 typedef boost::shared_ptr<char> shared_ptr_t; 00334 shared_ptr_t sp(new char('n')); 00335 std::vector<shared_ptr_t> sp_vec(arraySize); 00336 TEUCHOS_START_PERF_OUTPUT_TIMER_INNERLOOP(outputter, numActualLoops, arraySize) 00337 { 00338 for (int i=0; i < arraySize; ++i) { 00339 sp_vec[i] = sp; 00340 } 00341 } 00342 } 00343 TEUCHOS_END_PERF_OUTPUT_TIMER(outputter, spTime); 00344 #else 00345 outputter.outputField("-"); 00346 #endif 00347 00348 // RCP 00349 { 00350 RCP<char> p(new char('n')); 00351 std::vector<RCP<char> > p_vec(arraySize); 00352 TEUCHOS_START_PERF_OUTPUT_TIMER_INNERLOOP(outputter, numActualLoops, arraySize) 00353 { 00354 for (int i=0; i < arraySize; ++i) { 00355 p_vec[i] = p; 00356 // NOTE: This assignment operation tests the copy constructor and 00357 // the swap function. This calls both bind() and unbind() 00358 // underneath. 00359 } 00360 } 00361 } 00362 TEUCHOS_END_PERF_OUTPUT_TIMER(outputter, rcpTime); 00363 00364 // RCP/raw 00365 const double rcpRawRatio = rcpTime / rawPtrTime; 00366 finalRcpRawRatio = TEUCHOS_MIN(rcpRawRatio, finalRcpRawRatio); 00367 outputter.outputField(rcpRawRatio); 00368 00369 #ifdef HAVE_TEUCHOS_BOOST 00370 // RCP/shared_ptr 00371 const double rcpSpRatio = rcpTime / spTime; 00372 finalRcpSpRatio = TEUCHOS_MIN(rcpSpRatio, finalRcpSpRatio); 00373 outputter.outputField(rcpSpRatio); 00374 #else 00375 outputter.outputField("-"); 00376 #endif 00377 00378 outputter.nextRow(); 00379 00380 arraySize *= 4; 00381 00382 } 00383 00384 out << "\n"; 00385 TEST_COMPARE( finalRcpRawRatio, <=, maxRcpRawAdjustRefCountRatio ); 00386 #ifdef HAVE_TEUCHOS_BOOST 00387 out << "\n"; 00388 TEST_COMPARE( finalRcpSpRatio, <=, maxRcpSpAdjustRefCountRatio ); 00389 out << "\n"; 00390 #else 00391 (void)finalRcpSpRatio; 00392 #endif 00393 00394 } 00395 00396 00397 TEUCHOS_UNIT_TEST( RCP, dereferenceOverhead ) 00398 { 00399 00400 typedef Teuchos::TabularOutputter TO; 00401 00402 const double relTestCost = 1e-4; 00403 const int maxLoopIters = 1000; 00404 const double numInnerLoops = relCpuSpeed / relTestCost; 00405 00406 out << "\n" 00407 << "Messuring the overhead of dereferencing RCP, shared_ptr and a raw pointer.\n" 00408 << "\n"; 00409 00410 TabularOutputter outputter(out); 00411 outputter.setFieldTypePrecision(TO::DOUBLE, dblPrec); 00412 outputter.setFieldTypePrecision(TO::INT, intPrec); 00413 00414 outputter.pushFieldSpec("array dim", TO::INT); 00415 outputter.pushFieldSpec("num loops", TO::INT); 00416 outputter.pushFieldSpec("raw", TO::DOUBLE); 00417 outputter.pushFieldSpec("shared_ptr", TO::DOUBLE); 00418 outputter.pushFieldSpec("RCP", TO::DOUBLE); 00419 outputter.pushFieldSpec("RCP/raw", TO::DOUBLE); 00420 outputter.pushFieldSpec("RCP/shared_ptr", TO::DOUBLE); 00421 00422 outputter.outputHeader(); 00423 00424 double finalRcpRawRatio = 100000.0; 00425 int arraySize = 64; 00426 const int dummy_int_val = 1; 00427 int overall_dummy_int_out = 0; 00428 00429 00430 for ( 00431 int test_case_k = 0; 00432 test_case_k < maxLoopIters && arraySize <= maxArraySize; 00433 ++test_case_k 00434 ) 00435 { 00436 00437 // array dim 00438 outputter.outputField(arraySize); 00439 00440 // num loops 00441 const int numActualLoops = 00442 TEUCHOS_MAX( 00443 static_cast<int>( 00444 (numInnerLoops / arraySize) 00445 * std::log(static_cast<double>(arraySize+1)) 00446 ), 00447 1 00448 ); 00449 outputter.outputField(numActualLoops); 00450 00451 int dummy_int_out = 0; 00452 00453 // raw 00454 { 00455 int dummy_int = dummy_int_val; 00456 std::vector<int*> p_raw_vec(arraySize); 00457 for (int i=0; i < arraySize; ++i) { 00458 p_raw_vec[i] = &dummy_int; 00459 } 00460 dummy_int_out = 0; 00461 TEUCHOS_START_PERF_OUTPUT_TIMER_INNERLOOP(outputter, numActualLoops, arraySize) 00462 { 00463 for (int i=0; i < arraySize; ++i) { 00464 dummy_int_out += *p_raw_vec[i]; 00465 } 00466 } 00467 } 00468 TEUCHOS_END_PERF_OUTPUT_TIMER(outputter, rawPtrTime); 00469 overall_dummy_int_out += dummy_int_out; 00470 00471 // shared_ptr 00472 #ifdef HAVE_TEUCHOS_BOOST 00473 { 00474 typedef boost::shared_ptr<int> shared_ptr_t; 00475 shared_ptr_t sp(new int(dummy_int_val)); 00476 std::vector<shared_ptr_t> sp_vec(arraySize); 00477 for (int i=0; i < arraySize; ++i) { 00478 sp_vec[i] = sp; 00479 } 00480 dummy_int_out = 0; 00481 TEUCHOS_START_PERF_OUTPUT_TIMER_INNERLOOP(outputter, numActualLoops, arraySize) 00482 { 00483 for (int i=0; i < arraySize; ++i) { 00484 dummy_int_out += *sp_vec[i]; 00485 } 00486 } 00487 } 00488 TEUCHOS_END_PERF_OUTPUT_TIMER(outputter, spTime); 00489 overall_dummy_int_out += dummy_int_out; 00490 #else 00491 outputter.outputField("-"); 00492 #endif 00493 00494 // RCP 00495 { 00496 RCP<int> p(new int(dummy_int_val)); 00497 std::vector<RCP<int> > p_vec(arraySize); 00498 for (int i=0; i < arraySize; ++i) { 00499 p_vec[i] = p; 00500 } 00501 dummy_int_out = 0; 00502 TEUCHOS_START_PERF_OUTPUT_TIMER_INNERLOOP(outputter, numActualLoops, arraySize) 00503 { 00504 for (int i=0; i < arraySize; ++i) { 00505 dummy_int_out += *p_vec[i]; 00506 } 00507 } 00508 } 00509 TEUCHOS_END_PERF_OUTPUT_TIMER(outputter, rcpTime); 00510 overall_dummy_int_out += dummy_int_out; 00511 00512 // RCP/raw 00513 const double rcpRawRatio = rcpTime / rawPtrTime; 00514 finalRcpRawRatio = TEUCHOS_MIN(rcpRawRatio, finalRcpRawRatio); 00515 outputter.outputField(rcpRawRatio); 00516 00517 #ifdef HAVE_TEUCHOS_BOOST 00518 // RCP/shared_ptr 00519 const double rcpSpRatio = rcpTime / spTime; 00520 outputter.outputField(rcpSpRatio); 00521 #else 00522 outputter.outputField("-"); 00523 #endif 00524 00525 outputter.nextRow(); 00526 00527 arraySize *= 4; 00528 00529 } 00530 00531 out << "\n"; 00532 TEST_COMPARE( finalRcpRawRatio, <=, maxRcpRawObjAccessRatio ); 00533 out << "\n"; 00534 00535 // This silly variable must be accumulated or compilers like MSVC++ will 00536 // optimize away the loops! 00537 if (overall_dummy_int_out == 0) 00538 success = false; 00539 00540 } 00541 00542 00543 struct SomeStruct { 00544 SomeStruct(int member_in) : member(member_in) {} 00545 int member; 00546 }; 00547 00548 00549 TEUCHOS_UNIT_TEST( RCP, memberAccessOverhead ) 00550 { 00551 00552 typedef Teuchos::TabularOutputter TO; 00553 00554 const double relTestCost = 1e-4; 00555 const int maxLoopIters = 1000; 00556 const double numInnerLoops = relCpuSpeed / relTestCost; 00557 00558 out << "\n" 00559 << "Messuring the overhead of dereferencing RCP, shared_ptr and a raw pointer.\n" 00560 << "\n"; 00561 00562 TabularOutputter outputter(out); 00563 outputter.setFieldTypePrecision(TO::DOUBLE, dblPrec); 00564 outputter.setFieldTypePrecision(TO::INT, intPrec); 00565 00566 outputter.pushFieldSpec("array dim", TO::INT); 00567 outputter.pushFieldSpec("num loops", TO::INT); 00568 outputter.pushFieldSpec("raw", TO::DOUBLE); 00569 outputter.pushFieldSpec("shared_ptr", TO::DOUBLE); 00570 outputter.pushFieldSpec("RCP", TO::DOUBLE); 00571 outputter.pushFieldSpec("RCP/raw", TO::DOUBLE); 00572 outputter.pushFieldSpec("RCP/shared_ptr", TO::DOUBLE); 00573 00574 outputter.outputHeader(); 00575 00576 double finalRcpRawRatio = 100000.0; 00577 int arraySize = 64; 00578 const int dummy_int_val = 1; 00579 int overall_dummy_int_out = 0; 00580 00581 for ( 00582 int test_case_k = 0; 00583 test_case_k < maxLoopIters && arraySize <= maxArraySize; 00584 ++test_case_k 00585 ) 00586 { 00587 00588 // array dim 00589 outputter.outputField(arraySize); 00590 00591 // num loops 00592 const int numActualLoops = 00593 TEUCHOS_MAX( 00594 static_cast<int>( 00595 (numInnerLoops / arraySize) 00596 * std::log(static_cast<double>(arraySize+1)) 00597 ), 00598 1 00599 ); 00600 outputter.outputField(numActualLoops); 00601 00602 int dummy_int_out = 0; 00603 00604 // raw 00605 { 00606 SomeStruct dummy_SomeStruct(dummy_int_val); 00607 std::vector<SomeStruct*> p_raw_vec(arraySize); 00608 for (int i=0; i < arraySize; ++i) { 00609 p_raw_vec[i] = &dummy_SomeStruct; 00610 } 00611 dummy_int_out = 0; 00612 TEUCHOS_START_PERF_OUTPUT_TIMER_INNERLOOP(outputter, numActualLoops, arraySize) 00613 { 00614 for (int i=0; i < arraySize; ++i) { 00615 dummy_int_out += p_raw_vec[i]->member; 00616 } 00617 } 00618 } 00619 TEUCHOS_END_PERF_OUTPUT_TIMER(outputter, rawPtrTime); 00620 overall_dummy_int_out += dummy_int_out; 00621 00622 // shared_ptr 00623 #ifdef HAVE_TEUCHOS_BOOST 00624 { 00625 typedef boost::shared_ptr<SomeStruct> shared_ptr_t; 00626 shared_ptr_t sp(new SomeStruct(dummy_int_val)); 00627 std::vector<shared_ptr_t> sp_vec(arraySize); 00628 for (int i=0; i < arraySize; ++i) { 00629 sp_vec[i] = sp; 00630 } 00631 dummy_int_out = 0; 00632 TEUCHOS_START_PERF_OUTPUT_TIMER_INNERLOOP(outputter, numActualLoops, arraySize) 00633 { 00634 for (int i=0; i < arraySize; ++i) { 00635 dummy_int_out += sp_vec[i]->member; 00636 } 00637 } 00638 } 00639 TEUCHOS_END_PERF_OUTPUT_TIMER(outputter, spTime); 00640 overall_dummy_int_out += dummy_int_out; 00641 #else 00642 outputter.outputField("-"); 00643 #endif 00644 00645 // RCP 00646 { 00647 RCP<SomeStruct> p(new SomeStruct(dummy_int_val)); 00648 std::vector<RCP<SomeStruct> > p_vec(arraySize); 00649 for (int i=0; i < arraySize; ++i) { 00650 p_vec[i] = p; 00651 } 00652 dummy_int_out = 0; 00653 TEUCHOS_START_PERF_OUTPUT_TIMER_INNERLOOP(outputter, numActualLoops, arraySize) 00654 { 00655 for (int i=0; i < arraySize; ++i) { 00656 dummy_int_out += p_vec[i]->member; 00657 } 00658 } 00659 } 00660 TEUCHOS_END_PERF_OUTPUT_TIMER(outputter, rcpTime); 00661 overall_dummy_int_out += dummy_int_out; 00662 00663 // RCP/raw 00664 const double rcpRawRatio = rcpTime / rawPtrTime; 00665 finalRcpRawRatio = TEUCHOS_MIN(rcpRawRatio, finalRcpRawRatio); 00666 outputter.outputField(rcpRawRatio); 00667 00668 #ifdef HAVE_TEUCHOS_BOOST 00669 // RCP/shared_ptr 00670 const double rcpSpRatio = rcpTime / spTime; 00671 outputter.outputField(rcpSpRatio); 00672 #else 00673 outputter.outputField("-"); 00674 #endif 00675 00676 outputter.nextRow(); 00677 00678 arraySize *= 4; 00679 00680 } 00681 00682 out << "\n"; 00683 TEST_COMPARE( finalRcpRawRatio, <=, maxRcpRawObjAccessRatio ); 00684 out << "\n"; 00685 00686 // This silly variable must be accumulated or compilers like MSVC++ will 00687 // optimize away the loops! 00688 if (overall_dummy_int_out == 0) 00689 success = false; 00690 00691 } 00692 00693 00694 00695 00696 00697 00698 00699 } // namespace
1.7.6.1