Teuchos Package Browser (Single Doxygen Collection) Version of the Day
Loading...
Searching...
No Matches
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
50namespace {
51
52
53using Teuchos::null;
54using Teuchos::RCP;
55using Teuchos::rcp;
57using Teuchos::Ordinal;
58
59
60double relCpuSpeed = 1e-2;
61int maxArraySize = 10000;
62double maxArrayBracketRatio =100.0;
63double maxArrayIterRatio = 200.0;
64double maxArrayRCPSelfIterRatio =200.0;
65
66const int minArraySize = 100;
67const int maxLoopIters = 1000;
68const int intPrec = 8;
69const 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
101TEUCHOS_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 =
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
209TEUCHOS_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 =
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
300TEUCHOS_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 =
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
390TEUCHOS_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 =
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
502TEUCHOS_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 =
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
598TEUCHOS_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 =
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
693TEUCHOS_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 =
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
Templated array class derived from the STL std::vector.
#define TEUCHOS_MIN(x, y)
#define TEUCHOS_MAX(x, y)
#define TEST_COMPARE(v1, comp, v2)
Assert that v1 comp v2 (where comp = '==', '>=", "!=", etc).
#define TEUCHOS_STATIC_SETUP()
Run setup code statically in a translation unit.
#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_START_PERF_OUTPUT_TIMER_INNERLOOP(OUTPUTTER, NUMLOOPS, NUMINNERLOOPS)
Start a timer block using a TabularOutputter object .
Unit testing support.
#define TEUCHOS_UNIT_TEST(TEST_GROUP, TEST_NAME)
Macro for defining a (non-templated) unit test.
Reference-counted smart pointer for managing arrays.
T * iterator
Nonconstant iterator type used if bounds checking is disabled.
iterator begin() const
Return an iterator to beginning of the array of data.
iterator end() const
Return an iterator to past the end of the array of data.
Nonowning array view.
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.
pointer iterator
Type of a nonconst iterator.
Replacement for std::vector that is compatible with the Teuchos Memory Management classes.
std::vector< T >::iterator iterator
The type of a forward iterator.
Class that helps parse command line input arguments from (argc,argv[]) and set options.
void setOption(const char option_true[], const char option_false[], bool *option_val, const char documentation[]=NULL)
Set a boolean option.
Smart reference counting pointer class for automatic garbage collection.
Utility class that makes it easy to create formatted tables of output.
static CommandLineProcessor & getCLP()
Return the CLP to add options to.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Deprecated.