Skip to content

Commit a591e1a

Browse files
committed
revision: more thorough benchmarking, change NDEBUG hardening default to IGNORE
Signed-off-by: Larry Gritz <lg@larrygritz.com>
1 parent ac9c430 commit a591e1a

4 files changed

Lines changed: 65 additions & 39 deletions

File tree

src/build-scripts/ci-benchmark.bash

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,14 @@ ls build
1313
ls $BUILD_BIN_DIR
1414

1515
mkdir -p build/benchmarks
16-
for t in image_span_test ; do
16+
for t in image_span_test span_test ; do
1717
echo
1818
echo
1919
echo "$t"
2020
echo "========================================================"
21-
${BUILD_BIN_DIR}/$t > build/benchmarks/$t.out
22-
cat build/benchmarks/$t.out
21+
OpenImageIO_CI=0 ${BUILD_BIN_DIR}/$t | tee build/benchmarks/$t.out
22+
# Note: set OpenImageIO_CI=0 to avoid CI-specific automatic reduction of
23+
# the number of trials and iterations.
2324
echo "========================================================"
2425
echo "========================================================"
2526
echo

src/cmake/compiler.cmake

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -499,12 +499,12 @@ endif ()
499499
# https://cheatsheetseries.owasp.org/cheatsheets/C-Based_Toolchain_Hardening_Cheat_Sheet.html
500500

501501
if (${CMAKE_BUILD_TYPE} STREQUAL "Debug")
502-
set (${PROJ_NAME}_HARDENING_DEFAULT 2)
502+
set (${PROJ_NAME}_HARDENING_DEFAULT 2) # Extensive
503503
else ()
504-
set (${PROJ_NAME}_HARDENING_DEFAULT 1)
504+
set (${PROJ_NAME}_HARDENING_DEFAULT 1) # Fast
505505
endif ()
506506
set_cache (${PROJ_NAME}_HARDENING ${${PROJ_NAME}_HARDENING_DEFAULT}
507-
"Turn on security hardening features 0, 1, 2, 3")
507+
"Turn on security hardening features 0=none, 1=fast, 2=extensive, 3=debug")
508508
# Implementation:
509509
add_compile_definitions (${PROJ_NAME}_HARDENING_DEFAULT=${${PROJ_NAME}_HARDENING})
510510
if (${PROJ_NAME}_HARDENING GREATER_EQUAL 1)

src/include/OpenImageIO/dassert.h

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -39,41 +39,44 @@
3939
#define OIIO_HARDENING_DEBUG 3
4040

4141
// OIIO_HARDENING_DEFAULT defines the default hardening level we actually use.
42-
// By default, we use NONE for release builds and DEBUG for debug builds. But
43-
// any translation unit (including clients of OIIO) may override this by
44-
// defining OIIO_HARDENING_DEFAULT before including any OIIO headers. But note
45-
// that this only affects calls to inline functions or templates defined in
46-
// the headers. Non-inline functions compiled into the OIIO library, including
47-
// OIIO internal code itself, will have been compiled with whatever hardening
48-
// level was selected when the library was built.
42+
// By default, we use FAST for release builds and DEBUG for debug builds. But
43+
// it can be overridden:
44+
// - For OIIO internals, at OIIO build time with the `OIIO_HARDENING` CMake
45+
// variable.
46+
// - For other projects using OIIO's headers, any translation unit may
47+
// override this by defining OIIO_HARDENING_DEFAULT before including any
48+
// OIIO headers. But note that this only affects calls to inline functions
49+
// or templates defined in the headers. Non-inline functions compiled into
50+
// the OIIO library itself will have been compiled with whatever hardening
51+
// level was selected when the library was built.
4952
#ifndef OIIO_HARDENING_DEFAULT
5053
# ifdef NDEBUG
51-
# define OIIO_HARDENING_DEFAULT OIIO_HARDENING_NONE
54+
# define OIIO_HARDENING_DEFAULT OIIO_HARDENING_FAST
5255
# else
5356
# define OIIO_HARDENING_DEFAULT OIIO_HARDENING_DEBUG
5457
# endif
5558
#endif
5659

5760

58-
/// Choices for what to do when a contract assertion fails.
59-
/// This mimics the C++26 standard's std::contract behavior.
61+
// Choices for what to do when a contract assertion fails.
62+
// This mimics the C++26 standard's std::contract behavior.
6063
#define OIIO_ASSERTION_RESPONSE_IGNORE 0
6164
#define OIIO_ASSERTION_RESPONSE_OBSERVE 1
6265
#define OIIO_ASSERTION_RESPONSE_ENFORCE 2
6366
#define OIIO_ASSERTION_RESPONSE_QUICK_ENFORCE 3
6467

6568
// OIIO_ASSERTION_RESPONSE_DEFAULT defines the default response to failed
66-
// contract assertions. By default, in NONE hardening mode and in release
67-
// builds, we do nothing. In all other cases, we abort. But any translation
69+
// contract assertions. By default, we enforce them, UNLESS we are a release
70+
// mode build that has set the hardening mode to NONE. But any translation
6871
// unit (including clients of OIIO) may override this by defining
6972
// OIIO_ASSERTION_RESPONSE_DEFAULT before including any OIIO headers. But note
7073
// that this only affects calls to inline functions or templates defined in
71-
// the headers. Non-inline functions compiled into the OIIO library, including
72-
// OIIO internal code itself, will have been compiled with whatever response
73-
// was selected when the library was built.
74+
// the headers. Non-inline functions compiled into the OIIO library itself
75+
// will have been compiled with whatever response was selected when the
76+
// library was built.
7477
#ifndef OIIO_ASSERTION_RESPONSE_DEFAULT
7578
# if OIIO_HARDENING_DEFAULT == OIIO_HARDENING_NONE && defined(NDEBUG)
76-
# define OIIO_ASSERTION_RESPONSE_DEFAULT OIIO_ASSERTION_RESPONSE_ENFORCE
79+
# define OIIO_ASSERTION_RESPONSE_DEFAULT OIIO_ASSERTION_RESPONSE_IGNORE
7780
# else
7881
# define OIIO_ASSERTION_RESPONSE_DEFAULT OIIO_ASSERTION_RESPONSE_ENFORCE
7982
# endif

src/libutil/span_test.cpp

Lines changed: 39 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -485,21 +485,38 @@ benchmark_span()
485485
{
486486
Benchmarker bench;
487487
bench.iterations(iterations).trials(ntrials);
488-
bench.work(1000);
489-
std::array<float, 1000> f;
490-
std::fill(f.begin(), f.end(), 1.0f);
491-
int sum = 0;
488+
const size_t N = 1000;
489+
// bench.work(N);
490+
std::array<float, N> fstdarr;
491+
std::fill(fstdarr.begin(), fstdarr.end(), 1.0f);
492+
bench("pointer operator[]", [&]() {
493+
float* fptr(fstdarr.data());
494+
float t = 0.0f;
495+
for (size_t i = 0; i < N; ++i)
496+
DoNotOptimize(t += fptr[i]);
497+
});
498+
bench("std::array operator[]", [&]() {
499+
float t = 0.0f;
500+
for (size_t i = 0; i < N; ++i)
501+
DoNotOptimize(t += fstdarr[i]);
502+
});
492503
bench("span operator[]", [&]() {
493-
int t = 0;
494-
for (size_t i = 0; i < f.size(); ++i)
495-
DoNotOptimize(t += f[i]);
496-
sum += t;
504+
span<float> fspan(fstdarr);
505+
float t = 0.0f;
506+
for (size_t i = 0; i < N; ++i)
507+
DoNotOptimize(t += fspan[i]);
508+
});
509+
bench("span unsafe indexing", [&]() {
510+
span<float> fspan(fstdarr);
511+
float t = 0.0f;
512+
for (size_t i = 0; i < N; ++i)
513+
DoNotOptimize(t += fspan.data()[i]);
497514
});
498515
bench("span range", [&]() {
499-
int t = 0;
500-
for (auto x : f)
516+
span<float> fspan(fstdarr);
517+
float t = 0.0f;
518+
for (auto x : fspan)
501519
DoNotOptimize(t += x);
502-
sum += t;
503520
});
504521
}
505522

@@ -508,13 +525,18 @@ benchmark_span()
508525
int
509526
main(int argc, char* argv[])
510527
{
511-
#if !defined(NDEBUG) || defined(OIIO_CI) || defined(OIIO_CODE_COVERAGE)
512-
// For the sake of test time, reduce the default iterations for DEBUG,
513-
// CI, and code coverage builds. Explicit use of --iters or --trials
514-
// will override this, since it comes before the getargs() call.
515-
iterations /= 10;
516-
ntrials = 1;
528+
// For the sake of test time, reduce the default number of benchmarking
529+
// trials and iterations for DEBUG, CI, and code coverage builds. Explicit
530+
// use of --iters or --trials will override this, since it comes before
531+
// the getargs() call.
532+
if (Strutil::eval_as_bool(Sysutil::getenv("OpenImageIO_CI"))
533+
#if !defined(NDEBUG) || defined(OIIO_CODE_COVERAGE)
534+
|| true
517535
#endif
536+
) {
537+
iterations /= 10;
538+
ntrials = 1;
539+
}
518540

519541
getargs(argc, argv);
520542

0 commit comments

Comments
 (0)