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
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
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
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.
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.
Concrete serial communicator subclass.
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.