View Issue Details

IDProjectCategoryView StatusLast Update
0026551Open CASCADEOCCT:Foundation Classespublic2016-06-09 09:50
Reporterabv Assigned Tobugmaster  
PrioritynormalSeverityfeature 
Status closedResolutionfixed 
Target Version7.0.0Fixed in Version7.0.0 
Summary0026551: Optimization of initialization of OCCT RTTI
DescriptionSince about version 6.5.0, OCCT RTTI system initializes all type descriptors defined in a library by the time of loading that library, via use of global variables. This is done in order to prevent possible data races if type descriptors are initialized upon first use (defined as static variables in corresponding getter function) in multithreaded applications.

In OCCT 7 (see 0024947) this feature is also implicitly used to optimize implementation of Standard_Type class: it stores pointers to strings defining its name (user and system) without copying it. This works only if each type descriptor is removed (when last library using it is unloaded) while these pointers are still valid (i.e. they are not part of another library that might have been unloaded previously). Initialization of all descriptors upon library loading is a means to ensure that.

C++11 adds a requirement that static variables should be protected against concurrent initialization (see http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2660.htm), this would make global variables for types not necessary. Unfortunately, this C++11 feature is not supported by Visual Studio until version 15 (GCC supports it since 4.3).

On the other side, even if not guaranteed by compiler, current implementation of OCCT RTTI should make initialization of type objects as static variables reasonably safe, even in case of concurrency. The point is that types are created in single function (Standard_Type::Register()) which is protected by
mutex. Hence, in the the worst case of concurrency static variable (handle to the type) will be initialized twice, by the same pointer. This will lead to twice incrementing reference counter, and leak of the type descriptor when library is unloaded. This should not be harmful (apart of minor memory leak).

Thus it is proposed to eliminate global type variables (Standard_Type::myInstance). The instance of Standard_Type should keep names of the type as string objects (not as pointers to string literals, as now -- these can be already unloaded by the time of destruction of the type descriptor).

That change should reduce time of loading OCCT libraries, and memory consumption (see timings attached to 0024947).
Steps To Reproducea) test perf fclasses bug24947

b) Start DRAW in Debug mode and then exit it by closing window; look for debug asserts
TagsNo tags attached.
Test case number

Attached Files

  • occt_perf-2.xlsx (12,912 bytes)

Relationships

related to 0026913 closedbugmaster Community Vulnerable mechanism in Standard_Type leads to assert 
related to 0027016 closedbugmaster Open CASCADE Restore global type descriptors for old compilers 
related to 0027584 closedabv Community __gnu_cxx::recursive_init_error thrown when concurrently accessing STANDARD_TYPE 

Activities

git

2015-12-12 19:08

administrator   ~0049070

Branch CR26551 has been created by abv.

SHA-1: e34b1b3e4ea2eca1b0dd70500e094343ddb6286c


Detailed log of new commits:

Author: abv
Date: Sat Dec 12 19:07:35 2015 +0300

    0026551: Optimization of initialization of OCCT RTTI
    
    Global instances of type descriptors are eliminated as unnecessary

Author: Roman Lygin
Date: Sun Nov 22 14:54:39 2015 +0400

    0026913: Vulnerable mechanism in Standard_Type leads to assert

abv

2015-12-13 23:11

manager  

occt_perf-2.xlsx (12,912 bytes)

abv

2015-12-13 23:24

manager   ~0049074

Change (based on previous fix made for 0026913) is pushed to CR26551, please review.

Note that by my measurements, it yields considerable decrease of size of libraries and load time of OCCT dlls (see attached Excel table), due to elimination of global variables holding type descriptors, and deferring initialization of descriptors to the time of first access.

On modern compilers (VC++ 14, GCC since 4.3, CLang since 2.9) it should be safe, since type descriptors instantiated as static variables in function should be protected against concurrent initialization. On older compilers, this should be safe anyway due to the fact that registry of the types is protected by mutex.

For status of compilers, see "magic statics" or N2660 in:
VC++: https://msdn.microsoft.com/ru-ru/library/hh567368.aspx#concurrencytable
GCC: https://gcc.gnu.org/projects/cxx0x.html
CLang: http://clang.llvm.org/cxx_status.html

kgv

2015-12-14 09:49

developer   ~0049077

Please test the patch.

bugmaster

2015-12-16 21:04

administrator   ~0049219

Fix has been tested with fix for issue 0026988

abv

2015-12-19 14:21

manager   ~0049321

This change proved to be unsafe for VC++ 10 and 12, see 0027016

git

2016-04-17 14:01

administrator   ~0053024

Branch CR26551 has been deleted by kgv.

SHA-1: e34b1b3e4ea2eca1b0dd70500e094343ddb6286c

Related Changesets

occt: master 795be040

2015-12-12 16:07:35

abv


Committer: bugmaster Details Diff
0026551: Optimization of initialization of OCCT RTTI

Global instances of type descriptors are eliminated as unnecessary
Affected Issues
0026551
mod - src/Standard/Standard_Type.cxx Diff File
mod - src/Standard/Standard_Type.hxx Diff File

Issue History

Date Modified Username Field Change
2015-08-12 07:20 abv New Issue
2015-08-12 07:20 abv Assigned To => abv
2015-11-22 13:59 abv Relationship added related to 0026913
2015-12-12 19:08 git Note Added: 0049070
2015-12-13 23:11 abv File Added: occt_perf-2.xlsx
2015-12-13 23:24 abv Note Added: 0049074
2015-12-13 23:24 abv Assigned To abv => kgv
2015-12-13 23:24 abv Status new => resolved
2015-12-14 09:49 kgv Note Added: 0049077
2015-12-14 09:49 kgv Assigned To kgv => bugmaster
2015-12-14 09:49 kgv Status resolved => reviewed
2015-12-16 21:04 bugmaster Note Added: 0049219
2015-12-16 21:04 bugmaster Status reviewed => tested
2015-12-18 15:25 bugmaster Changeset attached => occt master 795be040
2015-12-18 15:25 bugmaster Status tested => verified
2015-12-18 15:25 bugmaster Resolution open => fixed
2015-12-19 14:15 abv Relationship added related to 0027016
2015-12-19 14:21 abv Note Added: 0049321
2016-04-17 14:01 git Note Added: 0053024
2016-04-20 15:42 aiv Fixed in Version => 7.0.0
2016-04-20 15:50 aiv Status verified => closed
2016-06-09 09:50 Roman Lygin Relationship added related to 0027584