Commit Graph

8 Commits

Author SHA1 Message Date
Milian Wolff e95fb04202 QSharedPointer: optimize casts on rvalue shared pointers
When we are casting an rvalue QSharedPointer, we do not need to
pay the cost for the atomic refcount increment / decrement. Optimize
this by adding rvalue overloads that handle this specific case
directly.

Note that this is arguably a micro optimization since in most cases
the cost to create the pointer in the first place is going to dwarf
the cost for the atomic increment / decrement. But it starts to matter
for situations like `someConstObject.ptrGetter().dynamicCast()` - in
the common case the `ptrGetter()` returns by value and the cast can
then operate on an rvalue.

On my system, the benchmark speaks for itself:

```
./tests/benchmarks/corelib/tools/qsharedpointer/tst_bench_shared_ptr -perf -perfcounter cycles,instructions -iterations 100000 objectCast objectCast_rvalue
********* Start testing of tst_QSharedPointer *********
Config: Using QtTest library 6.9.0, Qt 6.9.0 (x86_64-little_endian-lp64 shared (dynamic) release build; by GCC 14.2.1 20240805), arch unknown
PASS   : tst_QSharedPointer::initTestCase()
PASS   : tst_QSharedPointer::objectCast()
RESULT : tst_QSharedPointer::objectCast():
     147.05521 CPU cycles per iteration (total: 14,705,522, iterations: 100000)
     147.00058 instructions per iteration, 1.000 instr/cycle (total: 14,700,058, iterations: 100000)
PASS   : tst_QSharedPointer::objectCast_rvalue()
RESULT : tst_QSharedPointer::objectCast_rvalue():
     52.00227 CPU cycles per iteration (total: 5,200,227, iterations: 100000)
     110.00056 instructions per iteration, 2.115 instr/cycle (total: 11,000,057, iterations: 100000)
PASS   : tst_QSharedPointer::cleanupTestCase()
Totals: 4 passed, 0 failed, 0 skipped, 0 blacklisted, 45ms
********* Finished testing of tst_QSharedPointer *********

./tests/benchmarks/corelib/tools/qsharedpointer/tst_bench_shared_ptr -perf -perfcounter cycles,instructions -iterations 100000 dynamicCast dynamicCast_rvalue
********* Start testing of tst_QSharedPointer *********
Config: Using QtTest library 6.9.0, Qt 6.9.0 (x86_64-little_endian-lp64 shared (dynamic) release build; by GCC 14.2.1 20240802), arch unknown
PASS   : tst_QSharedPointer::initTestCase()
PASS   : tst_QSharedPointer::dynamicCast()
RESULT : tst_QSharedPointer::dynamicCast():
     148.34457 CPU cycles per iteration (total: 14,834,457, iterations: 100000)
     120.00057 instructions per iteration, 0.809 instr/cycle (total: 12,000,058, iterations: 100000)
PASS   : tst_QSharedPointer::dynamicCast_rvalue()
RESULT : tst_QSharedPointer::dynamicCast_rvalue():
     25.00210 CPU cycles per iteration (total: 2,500,211, iterations: 100000)
     81.00057 instructions per iteration, 3.240 instr/cycle (total: 8,100,058, iterations: 100000)
PASS   : tst_QSharedPointer::cleanupTestCase()
Totals: 4 passed, 0 failed, 0 skipped, 0 blacklisted, 45ms
********* Finished testing of tst_QSharedPointer *********

./tests/benchmarks/corelib/tools/qsharedpointer/tst_bench_shared_ptr -perf -perfcounter cycles,instructions -iterations 100000 staticCast staticCast_rvalue
********* Start testing of tst_QSharedPointer *********
Config: Using QtTest library 6.9.0, Qt 6.9.0 (x86_64-little_endian-lp64 shared (dynamic) release build; by GCC 14.2.1 20240802), arch unknown
PASS   : tst_QSharedPointer::initTestCase()
PASS   : tst_QSharedPointer::staticCast()
RESULT : tst_QSharedPointer::staticCast():
     142.95894 CPU cycles per iteration (total: 14,295,894, iterations: 100000)
     54.00057 instructions per iteration, 0.378 instr/cycle (total: 5,400,058, iterations: 100000)
PASS   : tst_QSharedPointer::staticCast_rvalue()
RESULT : tst_QSharedPointer::staticCast_rvalue():
     14.00205 CPU cycles per iteration (total: 1,400,205, iterations: 100000)
     22.00056 instructions per iteration, 1.571 instr/cycle (total: 2,200,057, iterations: 100000)
PASS   : tst_QSharedPointer::cleanupTestCase()
Totals: 4 passed, 0 failed, 0 skipped, 0 blacklisted, 50ms
********* Finished testing of tst_QSharedPointer *********

./tests/benchmarks/corelib/tools/qsharedpointer/tst_bench_shared_ptr -perf -perfcounter cycles,instructions -iterations 100000 constCast constCast_rvalue
********* Start testing of tst_QSharedPointer *********
Config: Using QtTest library 6.9.0, Qt 6.9.0 (x86_64-little_endian-lp64 shared (dynamic) release build; by GCC 14.2.1 20240802), arch unknown
PASS   : tst_QSharedPointer::initTestCase()
PASS   : tst_QSharedPointer::constCast()
RESULT : tst_QSharedPointer::constCast():
     142.38115 CPU cycles per iteration (total: 14,238,116, iterations: 100000)
     54.00057 instructions per iteration, 0.379 instr/cycle (total: 5,400,058, iterations: 100000)
PASS   : tst_QSharedPointer::constCast_rvalue()
RESULT : tst_QSharedPointer::constCast_rvalue():
     13.00243 CPU cycles per iteration (total: 1,300,243, iterations: 100000)
     22.00057 instructions per iteration, 1.692 instr/cycle (total: 2,200,058, iterations: 100000)
PASS   : tst_QSharedPointer::cleanupTestCase()
Totals: 4 passed, 0 failed, 0 skipped, 0 blacklisted, 42ms
********* Finished testing of tst_QSharedPointer *********
```

[ChangeLog][QtCore][QSharedPointer] Optimized casts on rvalue shared
pointers.

Change-Id: I7dfb4d92253d6c60286d3903bc7aef66acab5689
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2024-09-05 12:44:46 +02:00
Lucie Gérard ff1039c217 Change license for tests files
According to QUIP-18 [1], all tests file should be
LicenseRef-Qt-Commercial OR GPL-3.0-only

[1]: https://contribute.qt-project.org/quips/18

Pick-to: 6.7
Task-number: QTBUG-121787
Change-Id: I9657df5d660820e56c96d511ea49d321c54682e8
Reviewed-by: Christian Ehrlicher <ch.ehrlicher@gmx.de>
2024-02-04 09:56:42 +01:00
Lucie Gérard 32df595275 Change the license of all CMakeLists.txt and *.cmake files to BSD
Task-number: QTBUG-105718
Change-Id: I5d3ef70a31235868b9be6cb479b7621bf2a8ba39
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Jörg Bornemann <joerg.bornemann@qt.io>
2022-08-23 23:58:42 +02:00
Lucie Gérard fb1b20eab3 Add license headers to cmake files
CMakeLists.txt and .cmake files of significant size
(more than 2 lines according to our check in tst_license.pl)
now have the copyright and license header.

Existing copyright statements remain intact

Task-number: QTBUG-88621
Change-Id: I3b98cdc55ead806ec81ce09af9271f9b95af97fa
Reviewed-by: Jörg Bornemann <joerg.bornemann@qt.io>
2022-08-03 17:14:55 +02:00
Alexandru Croitor 4d22405e48 CMake: Don't use PUBLIC_LIBRARIES for tests and test helpers
Change-Id: I9b7404e1d3a78fe0726ec0f5ce1461f6c209e90d
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
2022-07-28 14:46:53 +02:00
Marc Mutz 882fc48b9e tst_bench_shared_ptr: fix build with BOOST_NO_EXCEPTIONS
If, for whatever reason, BOOST_NO_EXCEPTIONS is defined, the user of
the Boost libraries is supposed to provide a definition of
boost::throw_exception, which we didn't.

We used to run into this only on ubsan builds, but it seems we now
have the problem on a regular Ubuntu 22.04 build, too (cf. bugreport).

Fix by adding the necessary definitions.

Fixes: QTBUG-104083
Pick-to: 6.4 6.3
Change-Id: I9b061a158a5b77e8d286bd7b40312e5bc63ee8de
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
2022-06-22 03:09:24 +02:00
Lucie Gérard 05fc3aef53 Use SPDX license identifiers
Replace the current license disclaimer in files by
a SPDX-License-Identifier.
Files that have to be modified by hand are modified.
License files are organized under LICENSES directory.

Task-number: QTBUG-67283
Change-Id: Id880c92784c40f3bbde861c0d93f58151c18b9f1
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Reviewed-by: Jörg Bornemann <joerg.bornemann@qt.io>
2022-05-16 16:37:38 +02:00
Marc Mutz 18113e22e9 Add a benchmark for QSharedPointer
Initial results with GCC:

Even though GCC's assembly looks rather bad because of the implicit
fall-back from atomics to non-atomics for single-threaded
applications, libstdc++'s shared_ptr still performs twice as fast as
QSharedPointer, proving that the branch predictor eats libstdc++'s
is-multi-threaded-check for breakfast and the two atomic operations of
a QSharedPointer copy vs. one for std::shared_ptr dominate the
run-time.

********* Start testing of tst_QSharedPointer *********
Config: Using QtTest library 6.2.0, Qt 6.2.0 (x86_64-little_endian-lp64 shared (dynamic) release build; by GCC 11.1.1 20210712), ubuntu 20.04
PASS   : tst_QSharedPointer::initTestCase()
PASS   : tst_QSharedPointer::refAndDeref_null_QSP_int()
RESULT : tst_QSharedPointer::refAndDeref_null_QSP_int():
     0.0000024 msecs per iteration (total: 81, iterations: 33554432)
PASS   : tst_QSharedPointer::refAndDeref_null_SSP_int()
RESULT : tst_QSharedPointer::refAndDeref_null_SSP_int():
     0.0000024 msecs per iteration (total: 81, iterations: 33554432)
PASS   : tst_QSharedPointer::refAndDeref_null_BSP_int()
RESULT : tst_QSharedPointer::refAndDeref_null_BSP_int():
     0.0000025 msecs per iteration (total: 87, iterations: 33554432)
PASS   : tst_QSharedPointer::refAndDeref_null_QSP_QString()
RESULT : tst_QSharedPointer::refAndDeref_null_QSP_QString():
     0.0000025 msecs per iteration (total: 86, iterations: 33554432)
PASS   : tst_QSharedPointer::refAndDeref_null_SSP_QString()
RESULT : tst_QSharedPointer::refAndDeref_null_SSP_QString():
     0.0000023 msecs per iteration (total: 80, iterations: 33554432)
PASS   : tst_QSharedPointer::refAndDeref_null_BSP_QString()
RESULT : tst_QSharedPointer::refAndDeref_null_BSP_QString():
     0.0000026 msecs per iteration (total: 88, iterations: 33554432)
PASS   : tst_QSharedPointer::refAndDeref_nonnull_QSP_int()
RESULT : tst_QSharedPointer::refAndDeref_nonnull_QSP_int():
     0.000019 msecs per iteration (total: 83, iterations: 4194304)
PASS   : tst_QSharedPointer::refAndDeref_nonnull_SSP_int()
RESULT : tst_QSharedPointer::refAndDeref_nonnull_SSP_int():
     0.000010 msecs per iteration (total: 90, iterations: 8388608)
PASS   : tst_QSharedPointer::refAndDeref_nonnull_BSP_int()
RESULT : tst_QSharedPointer::refAndDeref_nonnull_BSP_int():
     0.0000094 msecs per iteration (total: 79, iterations: 8388608)
PASS   : tst_QSharedPointer::refAndDeref_nonnull_QSP_QString()
RESULT : tst_QSharedPointer::refAndDeref_nonnull_QSP_QString():
     0.000017 msecs per iteration (total: 75, iterations: 4194304)
PASS   : tst_QSharedPointer::refAndDeref_nonnull_SSP_QString()
RESULT : tst_QSharedPointer::refAndDeref_nonnull_SSP_QString():
     0.000010 msecs per iteration (total: 90, iterations: 8388608)
PASS   : tst_QSharedPointer::refAndDeref_nonnull_BSP_QString()
RESULT : tst_QSharedPointer::refAndDeref_nonnull_BSP_QString():
     0.0000091 msecs per iteration (total: 77, iterations: 8388608)
PASS   : tst_QSharedPointer::threadedRefAndDeref_null_QSP_int()
RESULT : tst_QSharedPointer::threadedRefAndDeref_null_QSP_int():
     0.000016 msecs per iteration (total: 68, iterations: 4194304)
PASS   : tst_QSharedPointer::threadedRefAndDeref_null_SSP_int()
RESULT : tst_QSharedPointer::threadedRefAndDeref_null_SSP_int():
     0.000025 msecs per iteration (total: 53, iterations: 2097152)
PASS   : tst_QSharedPointer::threadedRefAndDeref_null_BSP_int()
RESULT : tst_QSharedPointer::threadedRefAndDeref_null_BSP_int():
     0.000027 msecs per iteration (total: 58, iterations: 2097152)
PASS   : tst_QSharedPointer::threadedRefAndDeref_null_QSP_QString()
RESULT : tst_QSharedPointer::threadedRefAndDeref_null_QSP_QString():
     0.000016 msecs per iteration (total: 71, iterations: 4194304)
PASS   : tst_QSharedPointer::threadedRefAndDeref_null_SSP_QString()
RESULT : tst_QSharedPointer::threadedRefAndDeref_null_SSP_QString():
     0.000027 msecs per iteration (total: 58, iterations: 2097152)
PASS   : tst_QSharedPointer::threadedRefAndDeref_null_BSP_QString()
RESULT : tst_QSharedPointer::threadedRefAndDeref_null_BSP_QString():
     0.000017 msecs per iteration (total: 73, iterations: 4194304)
PASS   : tst_QSharedPointer::threadedRefAndDeref_nonnull_QSP_int()
RESULT : tst_QSharedPointer::threadedRefAndDeref_nonnull_QSP_int():
     0.00073 msecs per iteration (total: 96, iterations: 131072)
PASS   : tst_QSharedPointer::threadedRefAndDeref_nonnull_SSP_int()
RESULT : tst_QSharedPointer::threadedRefAndDeref_nonnull_SSP_int():
     0.000408 msecs per iteration (total: 107, iterations: 262144)
PASS   : tst_QSharedPointer::threadedRefAndDeref_nonnull_BSP_int()
RESULT : tst_QSharedPointer::threadedRefAndDeref_nonnull_BSP_int():
     0.00033 msecs per iteration (total: 89, iterations: 262144)
PASS   : tst_QSharedPointer::threadedRefAndDeref_nonnull_QSP_QString()
RESULT : tst_QSharedPointer::threadedRefAndDeref_nonnull_QSP_QString():
     0.000877 msecs per iteration (total: 115, iterations: 131072)
PASS   : tst_QSharedPointer::threadedRefAndDeref_nonnull_SSP_QString()
RESULT : tst_QSharedPointer::threadedRefAndDeref_nonnull_SSP_QString():
     0.00033 msecs per iteration (total: 89, iterations: 262144)
PASS   : tst_QSharedPointer::threadedRefAndDeref_nonnull_BSP_QString()
RESULT : tst_QSharedPointer::threadedRefAndDeref_nonnull_BSP_QString():
     0.000385 msecs per iteration (total: 101, iterations: 262144)
PASS   : tst_QSharedPointer::cleanupTestCase()
Totals: 26 passed, 0 failed, 0 skipped, 0 blacklisted, 7995ms
********* Finished testing of tst_QSharedPointer *********

Change-Id: I0bed70142ffdbde6898ec0e27cb470b50fc0e97d
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
2021-07-27 14:58:41 +02:00