Teuchos Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Array_Performance_UnitTests.cpp
Go to the documentation of this file.
1 /*
2 // @HEADER
3 // ***********************************************************************
4 //
5 // Teuchos: Common Tools Package
6 // Copyright (2004) Sandia Corporation
7 //
8 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
9 // license for use of this work by or on behalf of the U.S. Government.
10 //
11 // Redistribution and use in source and binary forms, with or without
12 // modification, are permitted provided that the following conditions are
13 // met:
14 //
15 // 1. Redistributions of source code must retain the above copyright
16 // notice, this list of conditions and the following disclaimer.
17 //
18 // 2. Redistributions in binary form must reproduce the above copyright
19 // notice, this list of conditions and the following disclaimer in the
20 // documentation and/or other materials provided with the distribution.
21 //
22 // 3. Neither the name of the Corporation nor the names of the
23 // contributors may be used to endorse or promote products derived from
24 // this software without specific prior written permission.
25 //
26 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 //
38 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
39 //
40 // ***********************************************************************
41 // @HEADER
42 */
43 
46 
47 #include "Teuchos_Array.hpp"
48 
49 
50 namespace {
51 
52 
53 using Teuchos::null;
54 using Teuchos::RCP;
55 using Teuchos::rcp;
57 using Teuchos::Ordinal;
58 
59 
60 double relCpuSpeed = 1e-2;
61 int maxArraySize = 10000;
62 double maxArrayBracketRatio =100.0;
63 double maxArrayIterRatio = 200.0;
64 double maxArrayRCPSelfIterRatio =200.0;
65 
66 const int minArraySize = 100;
67 const int maxLoopIters = 1000;
68 const int intPrec = 8;
69 const int dblPrec = 6;
70 
72 {
75  clp.setOption(
76  "rel-cpu-speed", &relCpuSpeed,
77  "The relative speed of the CPU (higher means the machine runs faster)"
78  );
79  clp.setOption(
80  "max-array-size", &maxArraySize,
81  "The maximum size of the arrays created"
82  );
83  clp.setOption(
84  "max-array-bracket-ratio", &maxArrayBracketRatio,
85  "The max allowed CPU timing ratio of the Array[RCP,View] braket operator relative"
86  " to the std::vector braket operator."
87  );
88  clp.setOption(
89  "max-array-iter-ratio", &maxArrayIterRatio,
90  "The max allowed CPU timing ratio of the Array[RCP,View] iterators relative"
91  " to using raw pointers as iterators."
92  );
93  clp.setOption(
94  "max-arrayrcp-self-iter-ratio", &maxArrayRCPSelfIterRatio,
95  "The max allowed CPU timing ratio of the ArrayrCP as a self iterator relative"
96  " to raw pointer arithmetic."
97  );
98 }
99 
100 
101 TEUCHOS_UNIT_TEST( Array, braketOperatorOverhead )
102 {
103 
104  typedef Teuchos::TabularOutputter TO;
105 
106  const double relTestCost = 1e-4;
107 
108  const double numInnerLoops = relCpuSpeed / relTestCost;
109 
110  out << "\n"
111  << "Measuring the overhead of the Array braket operator relative to raw pointers.\n"
112  << "\n"
113  << "Number of loops = relCpuSpeed/relTestCost = "
114  << relCpuSpeed << "/" << relTestCost << " = " << numInnerLoops << "\n"
115  << "\n";
116 
117  TabularOutputter outputter(out);
118  outputter.setFieldTypePrecision(TO::DOUBLE, dblPrec);
119  outputter.setFieldTypePrecision(TO::INT, intPrec);
120 
121  outputter.pushFieldSpec("array dim", TO::INT);
122  outputter.pushFieldSpec("num loops", TO::INT);
123  outputter.pushFieldSpec("raw ptr", TO::DOUBLE);
124  outputter.pushFieldSpec("vector", TO::DOUBLE);
125  outputter.pushFieldSpec("Array", TO::DOUBLE);
126  outputter.pushFieldSpec("vector/raw", TO::DOUBLE);
127  outputter.pushFieldSpec("Array/raw", TO::DOUBLE);
128 
129  outputter.outputHeader();
130 
131  // Start out really big to make sure it fails if not set correctly!
132  double finalArrayBraketRatio = 100000.0;
133 
134  Ordinal arraySize = minArraySize;
135  for (int test_case_k = 0;
136  test_case_k < maxLoopIters && arraySize <= maxArraySize;
137  ++test_case_k
138  )
139  {
140 
141  // array dim
142  outputter.outputField(arraySize);
143 
144  // num loops
145  const int numActualLoops =
146  TEUCHOS_MAX(
147  static_cast<int>(
148  (numInnerLoops / arraySize)
149  * std::log(static_cast<double>(arraySize+1))
150  ),
151  1
152  );
153  outputter.outputField(numActualLoops);
154 
155  std::vector<double> vec(arraySize);
156 
157  // raw ptr
158  {
159  double *p_raw = &vec[0];
160  TEUCHOS_START_PERF_OUTPUT_TIMER_INNERLOOP(outputter, numActualLoops, arraySize)
161  {
162  for (Ordinal i=0; i < arraySize; ++i)
163  p_raw[i] = 0.0;
164  }
165  }
166  TEUCHOS_END_PERF_OUTPUT_TIMER(outputter, rawPtrTime);
167 
168  // vector
169  TEUCHOS_START_PERF_OUTPUT_TIMER_INNERLOOP(outputter, numActualLoops, arraySize)
170  {
171  for (Ordinal i=0; i < arraySize; ++i)
172  vec[i] = 0.0;
173  }
174  TEUCHOS_END_PERF_OUTPUT_TIMER(outputter, vectorTime);
175 
176  // Array
177  {
178  Teuchos::Array<double> a(arraySize);
179  TEUCHOS_START_PERF_OUTPUT_TIMER_INNERLOOP(outputter, numActualLoops, arraySize)
180  {
181  for (Ordinal i=0; i < arraySize; ++i)
182  a[i] = 0.0;
183  }
184  }
185  TEUCHOS_END_PERF_OUTPUT_TIMER(outputter, arrayTime);
186 
187  // vector/raw
188  const double vectorRatio = vectorTime / rawPtrTime;
189  outputter.outputField(vectorRatio);
190 
191  // Array/raw
192  const double arrayRatio = arrayTime / rawPtrTime;
193  outputter.outputField(arrayRatio);
194 
195  outputter.nextRow();
196 
197  arraySize *= 4;
198  finalArrayBraketRatio = TEUCHOS_MIN(arrayRatio, finalArrayBraketRatio);
199 
200  }
201 
202  out << "\n";
203  TEST_COMPARE( finalArrayBraketRatio, <=, maxArrayBracketRatio );
204  out << "\n";
205 
206 }
207 
208 
209 TEUCHOS_UNIT_TEST( ArrayView, braketOperatorOverhead )
210 {
211 
212  typedef Teuchos::TabularOutputter TO;
213 
214  const double relTestCost = 1e-4;
215 
216  const double numInnerLoops = relCpuSpeed / relTestCost;
217 
218  out << "\n"
219  << "Measuring the overhead of the ArrayView braket operator relative to raw pointers.\n"
220  << "\n"
221  << "Number of loops = relCpuSpeed/relTestCost = "
222  << relCpuSpeed << "/" << relTestCost << " = " << numInnerLoops << "\n"
223  << "\n";
224 
225  TabularOutputter outputter(out);
226  outputter.setFieldTypePrecision(TO::DOUBLE, dblPrec);
227  outputter.setFieldTypePrecision(TO::INT, intPrec);
228 
229  outputter.pushFieldSpec("array dim", TO::INT);
230  outputter.pushFieldSpec("num loops", TO::INT);
231  outputter.pushFieldSpec("raw ptr", TO::DOUBLE);
232  outputter.pushFieldSpec("ArrayView", TO::DOUBLE);
233  outputter.pushFieldSpec("ArrayView/raw", TO::DOUBLE);
234 
235  outputter.outputHeader();
236 
237  // Start out really big to make sure it fails if not set correctly!
238  double finalArrayViewBraketRatio = 100000.0;
239 
240  Ordinal arraySize = minArraySize;
241  for (int test_case_k = 0;
242  test_case_k < maxLoopIters && arraySize <= maxArraySize;
243  ++test_case_k
244  )
245  {
246 
247  // array dim
248  outputter.outputField(arraySize);
249 
250  // num loops
251  const int numActualLoops =
252  TEUCHOS_MAX(
253  static_cast<int>(
254  (numInnerLoops / arraySize)
255  * std::log(static_cast<double>(arraySize+1))
256  ),
257  1
258  );
259  outputter.outputField(numActualLoops);
260 
261  std::vector<double> vec(arraySize);
262 
263  // raw ptr
264  double *p_raw = &vec[0];
265  TEUCHOS_START_PERF_OUTPUT_TIMER_INNERLOOP(outputter, numActualLoops, arraySize)
266  {
267  for (Ordinal i=0; i < arraySize; ++i)
268  p_raw[i] = 0.0;
269  }
270  TEUCHOS_END_PERF_OUTPUT_TIMER(outputter, rawPtrTime);
271 
272  // ArrayView
273  Teuchos::Array<double> a(arraySize);
275  TEUCHOS_START_PERF_OUTPUT_TIMER_INNERLOOP(outputter, numActualLoops, arraySize)
276  {
277  for (Ordinal i=0; i < arraySize; ++i)
278  av[i] = 0.0;
279  }
280  TEUCHOS_END_PERF_OUTPUT_TIMER(outputter, arrayviewTime);
281 
282  // Array/raw
283  const double arrayviewRatio = arrayviewTime / rawPtrTime;
284  outputter.outputField(arrayviewRatio);
285 
286  outputter.nextRow();
287 
288  arraySize *= 4;
289  finalArrayViewBraketRatio = TEUCHOS_MIN(arrayviewRatio, finalArrayViewBraketRatio);
290 
291  }
292 
293  out << "\n";
294  TEST_COMPARE( finalArrayViewBraketRatio, <=, maxArrayBracketRatio );
295  out << "\n";
296 
297 }
298 
299 
300 TEUCHOS_UNIT_TEST( ArrayRCP, braketOperatorOverhead )
301 {
302 
303  typedef Teuchos::TabularOutputter TO;
304 
305  const double relTestCost = 1e-4;
306 
307  const double numInnerLoops = relCpuSpeed / relTestCost;
308 
309  out << "\n"
310  << "Measuring the overhead of the ArrayRCP braket operator relative to raw pointers.\n"
311  << "\n"
312  << "Number of loops = relCpuSpeed/relTestCost = "
313  << relCpuSpeed << "/" << relTestCost << " = " << numInnerLoops << "\n"
314  << "\n";
315 
316  TabularOutputter outputter(out);
317  outputter.setFieldTypePrecision(TO::DOUBLE, dblPrec);
318  outputter.setFieldTypePrecision(TO::INT, intPrec);
319 
320  outputter.pushFieldSpec("array dim", TO::INT);
321  outputter.pushFieldSpec("num loops", TO::INT);
322  outputter.pushFieldSpec("raw ptr", TO::DOUBLE);
323  outputter.pushFieldSpec("ArrayRCP", TO::DOUBLE);
324  outputter.pushFieldSpec("ArrayRCP/raw", TO::DOUBLE);
325 
326  outputter.outputHeader();
327 
328  // Start out really big to make sure it fails if not set correctly!
329  double finalArrayRCPBraketRatio = 100000.0;
330 
331  Ordinal arraySize = minArraySize;
332  for (int test_case_k = 0;
333  test_case_k < maxLoopIters && arraySize <= maxArraySize;
334  ++test_case_k
335  )
336  {
337 
338  // array dim
339  outputter.outputField(arraySize);
340 
341  // num loops
342  const int numActualLoops =
343  TEUCHOS_MAX(
344  static_cast<int>(
345  (numInnerLoops / arraySize)
346  * std::log(static_cast<double>(arraySize+1))
347  ),
348  1
349  );
350  outputter.outputField(numActualLoops);
351 
352  std::vector<double> vec(arraySize);
353 
354  // raw ptr
355  double *p_raw = &vec[0];
356  TEUCHOS_START_PERF_OUTPUT_TIMER_INNERLOOP(outputter, numActualLoops, arraySize)
357  {
358  for (Ordinal i=0; i < arraySize; ++i)
359  p_raw[i] = 0.0;
360  }
361  TEUCHOS_END_PERF_OUTPUT_TIMER(outputter, rawPtrTime);
362 
363  // ArrayRCP
364  Teuchos::ArrayRCP<double> arcp = Teuchos::arcp<double>(arraySize);
365  TEUCHOS_START_PERF_OUTPUT_TIMER_INNERLOOP(outputter, numActualLoops, arraySize)
366  {
367  for (Ordinal i=0; i < arraySize; ++i)
368  arcp[i] = 0.0;
369  }
370  TEUCHOS_END_PERF_OUTPUT_TIMER(outputter, arrayrcpTime);
371 
372  // Array/raw
373  const double arrayrcpRatio = arrayrcpTime / rawPtrTime;
374  outputter.outputField(arrayrcpRatio);
375 
376  outputter.nextRow();
377 
378  arraySize *= 4;
379  finalArrayRCPBraketRatio = TEUCHOS_MIN(arrayrcpRatio, finalArrayRCPBraketRatio);
380 
381  }
382 
383  out << "\n";
384  TEST_COMPARE( finalArrayRCPBraketRatio, <=, maxArrayBracketRatio );
385  out << "\n";
386 
387 }
388 
389 
390 TEUCHOS_UNIT_TEST( Array, iteratorOverhead )
391 {
392 
393  typedef Teuchos::TabularOutputter TO;
394 
395  const double relTestCost = 1e-4;
396 
397  const double numInnerLoops = relCpuSpeed / relTestCost;
398 
399  out << "\n"
400  << "Measuring the overhead of the Array iterators relative to raw pointers.\n"
401  << "\n"
402  << "Number of loops = relCpuSpeed/relTestCost = "
403  << relCpuSpeed << "/" << relTestCost << " = " << numInnerLoops << "\n"
404  << "\n";
405 
406  TabularOutputter outputter(out);
407  outputter.setFieldTypePrecision(TO::DOUBLE, dblPrec);
408  outputter.setFieldTypePrecision(TO::INT, intPrec);
409 
410  outputter.pushFieldSpec("array dim", TO::INT);
411  outputter.pushFieldSpec("num loops", TO::INT);
412  outputter.pushFieldSpec("raw ptr", TO::DOUBLE);
413  outputter.pushFieldSpec("vector", TO::DOUBLE);
414  outputter.pushFieldSpec("Array", TO::DOUBLE);
415  outputter.pushFieldSpec("vector/raw", TO::DOUBLE);
416  outputter.pushFieldSpec("Array/raw", TO::DOUBLE);
417 
418  outputter.outputHeader();
419 
420  // Start out really big to make sure it fails if not set correctly!
421  double finalArrayIterRatio = 100000.0;
422 
423  Ordinal arraySize = minArraySize;
424  for (int test_case_k = 0;
425  test_case_k < maxLoopIters && arraySize <= maxArraySize;
426  ++test_case_k
427  )
428  {
429 
430  // array dim
431  outputter.outputField(arraySize);
432 
433  // num loops
434  const int numActualLoops =
435  TEUCHOS_MAX(
436  static_cast<int>(
437  (numInnerLoops / arraySize)
438  * std::log(static_cast<double>(arraySize+1))
439  ),
440  1
441  );
442  outputter.outputField(numActualLoops);
443 
444  std::vector<double> vec(arraySize);
445 
446  // raw ptr
447  TEUCHOS_START_PERF_OUTPUT_TIMER_INNERLOOP(outputter, numActualLoops, arraySize)
448  {
449  double
450  *p_raw_itr = &vec[0],
451  *p_raw_end = &vec[0] + arraySize;
452  for ( ; p_raw_itr < p_raw_end; ++p_raw_itr)
453  *p_raw_itr = 0.0;
454  }
455  TEUCHOS_END_PERF_OUTPUT_TIMER(outputter, rawPtrTime);
456 
457  // vector
458  TEUCHOS_START_PERF_OUTPUT_TIMER_INNERLOOP(outputter, numActualLoops, arraySize)
459  {
460  std::vector<double>::iterator
461  vec_itr = vec.begin(),
462  vec_end = vec.end();
463  for ( ; vec_itr < vec_end; ++vec_itr)
464  *vec_itr = 0.0;
465  }
466  TEUCHOS_END_PERF_OUTPUT_TIMER(outputter, vectorTime);
467 
468  // Array
469  Teuchos::Array<double> a(arraySize);
470  TEUCHOS_START_PERF_OUTPUT_TIMER_INNERLOOP(outputter, numActualLoops, arraySize)
471  {
473  a_itr = a.begin(),
474  a_end = a.end();
475  for ( ; a_itr < a_end; ++a_itr)
476  *a_itr = 0.0;
477  }
478  TEUCHOS_END_PERF_OUTPUT_TIMER(outputter, arrayTime);
479 
480  // vector/raw
481  const double vectorRatio = vectorTime / rawPtrTime;
482  outputter.outputField(vectorRatio);
483 
484  // Array/raw
485  const double arrayRatio = arrayTime / rawPtrTime;
486  outputter.outputField(arrayRatio);
487 
488  outputter.nextRow();
489 
490  arraySize *= 4;
491  finalArrayIterRatio = TEUCHOS_MIN(arrayRatio, finalArrayIterRatio);
492 
493  }
494 
495  out << "\n";
496  TEST_COMPARE( finalArrayIterRatio, <=, maxArrayIterRatio );
497  out << "\n";
498 
499 }
500 
501 
502 TEUCHOS_UNIT_TEST( ArrayView, iteratorOverhead )
503 {
504 
505  typedef Teuchos::TabularOutputter TO;
506 
507  const double relTestCost = 1e-4;
508 
509  const double numInnerLoops = relCpuSpeed / relTestCost;
510 
511  out << "\n"
512  << "Measuring the overhead of the ArrayView iterators relative to raw pointers.\n"
513  << "\n"
514  << "Number of loops = relCpuSpeed/relTestCost = "
515  << relCpuSpeed << "/" << relTestCost << " = " << numInnerLoops << "\n"
516  << "\n";
517 
518  TabularOutputter outputter(out);
519  outputter.setFieldTypePrecision(TO::DOUBLE, dblPrec);
520  outputter.setFieldTypePrecision(TO::INT, intPrec);
521 
522  outputter.pushFieldSpec("array dim", TO::INT);
523  outputter.pushFieldSpec("num loops", TO::INT);
524  outputter.pushFieldSpec("raw ptr", TO::DOUBLE);
525  outputter.pushFieldSpec("ArrayView", TO::DOUBLE);
526  outputter.pushFieldSpec("ArrayView/raw", TO::DOUBLE);
527 
528  outputter.outputHeader();
529 
530  // Start out really big to make sure it fails if not set correctly!
531  double finalArrayViewIterRatio = 100000.0;
532 
533  Ordinal arraySize = minArraySize;
534  for (int test_case_k = 0;
535  test_case_k < maxLoopIters && arraySize <= maxArraySize;
536  ++test_case_k
537  )
538  {
539 
540  // array dim
541  outputter.outputField(arraySize);
542 
543  // num loops
544  const int numActualLoops =
545  TEUCHOS_MAX(
546  static_cast<int>(
547  (numInnerLoops / arraySize)
548  * std::log(static_cast<double>(arraySize+1))
549  ),
550  1
551  );
552  outputter.outputField(numActualLoops);
553 
554  std::vector<double> vec(arraySize);
555 
556  // raw ptr
557  TEUCHOS_START_PERF_OUTPUT_TIMER_INNERLOOP(outputter, numActualLoops, arraySize)
558  {
559  double
560  *p_raw_itr = &vec[0],
561  *p_raw_end = &vec[0] + arraySize;
562  for ( ; p_raw_itr < p_raw_end; ++p_raw_itr)
563  *p_raw_itr = 0.0;
564  }
565  TEUCHOS_END_PERF_OUTPUT_TIMER(outputter, rawPtrTime);
566 
567  // ArrayView
568  Teuchos::Array<double> a(arraySize);
570  TEUCHOS_START_PERF_OUTPUT_TIMER_INNERLOOP(outputter, numActualLoops, arraySize)
571  {
573  av_itr = av.begin(),
574  av_end = av.end();
575  for ( ; av_itr < av_end ; ++av_itr)
576  *av_itr = 0.0;
577  }
578  TEUCHOS_END_PERF_OUTPUT_TIMER(outputter, arrayviewTime);
579 
580  // ArrayView/raw
581  const double arrayviewRatio = arrayviewTime / rawPtrTime;
582  outputter.outputField(arrayviewRatio);
583 
584  outputter.nextRow();
585 
586  arraySize *= 4;
587  finalArrayViewIterRatio = TEUCHOS_MIN(arrayviewRatio, finalArrayViewIterRatio);
588 
589  }
590 
591  out << "\n";
592  TEST_COMPARE( finalArrayViewIterRatio, <=, maxArrayIterRatio );
593  out << "\n";
594 
595 }
596 
597 
598 TEUCHOS_UNIT_TEST( ArrayRCP, iteratorOverhead )
599 {
600 
601  typedef Teuchos::TabularOutputter TO;
602 
603  const double relTestCost = 1e-4;
604 
605  const double numInnerLoops = relCpuSpeed / relTestCost;
606 
607  out << "\n"
608  << "Measuring the overhead of the ArrayRCP iterators relative to raw pointers.\n"
609  << "\n"
610  << "Number of loops = relCpuSpeed/relTestCost = "
611  << relCpuSpeed << "/" << relTestCost << " = " << numInnerLoops << "\n"
612  << "\n";
613 
614  TabularOutputter outputter(out);
615  outputter.setFieldTypePrecision(TO::DOUBLE, dblPrec);
616  outputter.setFieldTypePrecision(TO::INT, intPrec);
617 
618  outputter.pushFieldSpec("array dim", TO::INT);
619  outputter.pushFieldSpec("num loops", TO::INT);
620  outputter.pushFieldSpec("raw ptr", TO::DOUBLE);
621  outputter.pushFieldSpec("ArrayRCP", TO::DOUBLE);
622  outputter.pushFieldSpec("ArrayRCP/raw", TO::DOUBLE);
623 
624  outputter.outputHeader();
625 
626  // Start out really big to make sure it fails if not set correctly!
627  double finalArrayRCPIterRatio = 100000.0;
628 
629  Ordinal arraySize = minArraySize;
630  for (int test_case_k = 0;
631  test_case_k < maxLoopIters && arraySize <= maxArraySize;
632  ++test_case_k
633  )
634  {
635 
636  // array dim
637  outputter.outputField(arraySize);
638 
639  // num loops
640  const int numActualLoops =
641  TEUCHOS_MAX(
642  static_cast<int>(
643  (numInnerLoops / arraySize)
644  * std::log(static_cast<double>(arraySize+1))
645  ),
646  1
647  );
648  outputter.outputField(numActualLoops);
649 
650  std::vector<double> vec(arraySize);
651 
652  // raw ptr
653  TEUCHOS_START_PERF_OUTPUT_TIMER_INNERLOOP(outputter, numActualLoops, arraySize)
654  {
655  double
656  *p_raw_itr = &vec[0],
657  *p_raw_end = &vec[0] + arraySize;
658  for ( ; p_raw_itr < p_raw_end; ++p_raw_itr)
659  *p_raw_itr = 0.0;
660  }
661  TEUCHOS_END_PERF_OUTPUT_TIMER(outputter, rawPtrTime);
662 
663  // ArrayRCP
664  Teuchos::ArrayRCP<double> ap = Teuchos::arcp<double>(arraySize);
665  TEUCHOS_START_PERF_OUTPUT_TIMER_INNERLOOP(outputter, numActualLoops, arraySize)
666  {
668  ap_itr = ap.begin(),
669  ap_end = ap.end();
670  for ( ; ap_itr < ap_end; ++ap_itr)
671  *ap_itr = 0.0;
672  }
673  TEUCHOS_END_PERF_OUTPUT_TIMER(outputter, arrayviewTime);
674 
675  // ArrayRCP/raw
676  const double arrayviewRatio = arrayviewTime / rawPtrTime;
677  outputter.outputField(arrayviewRatio);
678 
679  outputter.nextRow();
680 
681  arraySize *= 4;
682  finalArrayRCPIterRatio = TEUCHOS_MIN(arrayviewRatio, finalArrayRCPIterRatio);
683 
684  }
685 
686  out << "\n";
687  TEST_COMPARE( finalArrayRCPIterRatio, <=, maxArrayIterRatio );
688  out << "\n";
689 
690 }
691 
692 
693 TEUCHOS_UNIT_TEST( ArrayRCP, selfIteratorOverhead )
694 {
695 
696  typedef Teuchos::TabularOutputter TO;
697 
698  const double relTestCost = 1e-4;
699 
700  const double numInnerLoops = relCpuSpeed / relTestCost;
701 
702  out << "\n"
703  << "Measuring the overhead of the ArrayRCP as a self iterataor relative to raw pointers.\n"
704  << "\n"
705  << "Number of loops = relCpuSpeed/relTestCost = "
706  << relCpuSpeed << "/" << relTestCost << " = " << numInnerLoops << "\n"
707  << "\n";
708 
709  TabularOutputter outputter(out);
710  outputter.setFieldTypePrecision(TO::DOUBLE, dblPrec);
711  outputter.setFieldTypePrecision(TO::INT, intPrec);
712 
713  outputter.pushFieldSpec("array dim", TO::INT);
714  outputter.pushFieldSpec("num loops", TO::INT);
715  outputter.pushFieldSpec("raw ptr", TO::DOUBLE);
716  outputter.pushFieldSpec("ArrayRCP", TO::DOUBLE);
717  outputter.pushFieldSpec("ArrayRCP/raw", TO::DOUBLE);
718 
719  outputter.outputHeader();
720 
721  // Start out really big to make sure it fails if not set correctly!
722  double finalArrayRCPIterRatio = 100000.0;
723 
724  Ordinal arraySize = minArraySize;
725  for (int test_case_k = 0;
726  test_case_k < maxLoopIters && arraySize <= maxArraySize;
727  ++test_case_k
728  )
729  {
730 
731  // array dim
732  outputter.outputField(arraySize);
733 
734  // num loops
735  const int numActualLoops =
736  TEUCHOS_MAX(
737  static_cast<int>(
738  (numInnerLoops / arraySize)
739  * std::log(static_cast<double>(arraySize+1))
740  ),
741  1
742  );
743  outputter.outputField(numActualLoops);
744 
745  std::vector<double> vec(arraySize);
746 
747  // raw ptr
748  TEUCHOS_START_PERF_OUTPUT_TIMER_INNERLOOP(outputter, numActualLoops, arraySize)
749  {
750  double
751  *p_raw_itr = &vec[0],
752  *p_raw_end = &vec[0] + arraySize;
753  for ( ; p_raw_itr < p_raw_end; ++p_raw_itr)
754  *p_raw_itr = 0.0;
755  }
756  TEUCHOS_END_PERF_OUTPUT_TIMER(outputter, rawPtrTime);
757 
758  // ArrayRCP
759  Teuchos::ArrayRCP<double> ap = Teuchos::arcp<double>(arraySize);
760  TEUCHOS_START_PERF_OUTPUT_TIMER_INNERLOOP(outputter, numActualLoops, arraySize)
761  {
763  ap_itr = ap,
764  ap_end = ap + arraySize;
765  for ( ; ap_itr < ap_end; ++ap_itr)
766  *ap_itr = 0.0;
767  }
768  TEUCHOS_END_PERF_OUTPUT_TIMER(outputter, arrayviewTime);
769 
770  // ArrayRCP/raw
771  const double arrayviewRatio = arrayviewTime / rawPtrTime;
772  outputter.outputField(arrayviewRatio);
773 
774  outputter.nextRow();
775 
776  arraySize *= 4;
777  finalArrayRCPIterRatio = TEUCHOS_MIN(arrayviewRatio, finalArrayRCPIterRatio);
778 
779  }
780 
781  out << "\n";
782  TEST_COMPARE( finalArrayRCPIterRatio, <=, maxArrayRCPSelfIterRatio );
783  out << "\n";
784 
785 }
786 
787 
788 } // namespace
pointer iterator
Type of a nonconst iterator.
iterator begin() const
Return an iterator to beginning of the array of data.
static CommandLineProcessor & getCLP()
Return the CLP to add options to.
#define TEST_COMPARE(v1, comp, v2)
Assert that v1 comp v2 (where comp = &#39;==&#39;, &#39;&gt;=&quot;, &quot;!=", etc).
ArrayRCP< T > arcp(const RCP< Array< T > > &v)
Wrap an RCP&lt;Array&lt;T&gt; &gt; object as an ArrayRCP&lt;T&gt; object.
#define TEUCHOS_UNIT_TEST(TEST_GROUP, TEST_NAME)
Macro for defining a (non-templated) unit test.
Utility class that makes it easy to create formatted tables of output.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Deprecated.
void setOption(const char option_true[], const char option_false[], bool *option_val, const char documentation[]=NULL)
Set a boolean option.
Unit testing support.
#define TEUCHOS_START_PERF_OUTPUT_TIMER_INNERLOOP(OUTPUTTER, NUMLOOPS, NUMINNERLOOPS)
Start a timer block using a TabularOutputter object .
#define TEUCHOS_END_PERF_OUTPUT_TIMER(OUTPUTTER, VARNAME)
End a timer block, output the time field to a TabularOutputter object, and set a variable with the ti...
#define TEUCHOS_MAX(x, y)
Templated array class derived from the STL std::vector.
Nonowning array view.
iterator end() const
Return an iterator to past the end of the array of data.
Smart reference counting pointer class for automatic garbage collection.
T * iterator
Nonconstant iterator type used if bounds checking is disabled.
iterator end() const
Return an iterator to past the end of the array of data.
std::vector< T >::iterator iterator
The type of a forward iterator.
#define TEUCHOS_MIN(x, y)
Class that helps parse command line input arguments from (argc,argv[]) and set options.
iterator begin() const
Return an iterator to beginning of the array of data.
TEUCHOS_STATIC_SETUP()
Reference-counted smart pointer for managing arrays.