Teuchos Package Browser (Single Doxygen Collection)  Version of the Day
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 = 100.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.
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;>=", "!=", etc).
ArrayRCP< T > arcp(const RCP< Array< T > > &v)
Wrap an RCP<Array<T> > object as an ArrayRCP<T> 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.
iterator begin() const
Return an iterator to beginning of the array of data.
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)
iterator end() const
Return an iterator to past the end of the array of data.
iterator begin() const
Return an iterator to beginning of the array of data.
Templated array class derived from the STL std::vector.
Nonowning array view.
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.
TEUCHOS_STATIC_SETUP()
Reference-counted smart pointer for managing arrays.
Replacement for std::vector that is compatible with the Teuchos Memory Management classes...