Changeset 7806f91 for libcfa/src


Ignore:
Timestamp:
Jul 25, 2025, 3:29:48 PM (2 months ago)
Author:
Mike Brooks <mlbrooks@…>
Branches:
master
Children:
1eea589f, 29c6a7d
Parents:
7640ff5
Message:

Add code for reproducing performance numbers in thesis draft of 16a843

Location:
libcfa/src
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/collections/list.hfa

    r7640ff5 r7806f91  
    8080// part), by failing fast.
    8181
    82 #if defined( __x86_64 )
    83         // Preferred case: tag in the most-significant bit.  Dereference has been shown to segfault consistently.
    84         // Maintenance should list more architectures as "ok" here, to let them use the preferred case, when valid.
    85         #define ORIGIN_TAG_BITNO ( 8 * sizeof( size_t ) - 1 )
    86 #else
    87         // Fallback case: tag in the least-significant bit.  Dereference will often give an alignment error, but may not,
    88         // e.g. if accessing a char-typed member.  32-bit x86 uses the most- significant bit for real room on the heap.
    89         #define ORIGIN_TAG_BITNO 0
     82#ifdef __EXPERIMENTAL_DISABLE_OTAG__ // Perf experimention alt mode
     83
     84    // With origin tagging disabled, iteration never reports "no more elements."
     85    // In this mode, the list API is buggy.
     86    // This mode is used to quantify the cost of the normal tagging scheme.
     87
     88    #define ORIGIN_TAG_SET(p)   (p)
     89    #define ORIGIN_TAG_CLEAR(p) (p)
     90    #define ORIGIN_TAG_QUERY(p) 0
     91    #define ORIGIN_TAG_ASGN(p, v) (p)
     92    #define ORIGIN_TAG_EITHER(p, v) (p)
     93    #define ORIGIN_TAG_NEQ(v1, v2) 0
     94
     95#else // Normal
     96
     97    #if defined( __x86_64 )
     98        // Preferred case: tag in the most-significant bit.  Dereference
     99        // has been shown to segfault consistently.  Maintenance should
     100        // list more architectures as "ok" here, to let them use the
     101        // preferred case, when valid.
     102        #define ORIGIN_TAG_BITNO ( 8 * sizeof( size_t ) - 1 )
     103    #else
     104        // Fallback case: tag in the least-significant bit.  Dereference
     105        // will often give an alignment error, but may not, e.g. if
     106        // accessing a char-typed member.  32-bit x86 uses the most-
     107        // significant bit for real room on the heap.
     108        #define ORIGIN_TAG_BITNO 0
     109    #endif
     110
     111    #define ORIGIN_TAG_MASK (((size_t)1) << ORIGIN_TAG_BITNO)
     112
     113    #define ORIGIN_TAG_SET(p) ((p) |  ORIGIN_TAG_MASK)
     114    #define ORIGIN_TAG_CLEAR(p) ((p) & ~ORIGIN_TAG_MASK)
     115    #define ORIGIN_TAG_QUERY(p) ((p) &  ORIGIN_TAG_MASK)
     116
     117    #define ORIGIN_TAG_ASGN(p, v) ( \
     118        verify( ! ORIGIN_TAG_QUERY(p) && "p had no tagbit" ), \
     119        ORIGIN_TAG_EITHER((p), (v)) \
     120    )
     121
     122    #define ORIGIN_TAG_EITHER(p, v) ( \
     123        verify( ! ORIGIN_TAG_CLEAR(v) && "v is a pure tagbit" ), \
     124        ( (p) | (v) ) \
     125    )
     126
     127    #define ORIGIN_TAG_NEQ(v1, v2) ( \
     128        verify( ! ORIGIN_TAG_CLEAR(v1) && "v1 is a pure tagbit" ), \
     129        verify( ! ORIGIN_TAG_CLEAR(v2) && "v2 is a pure tagbit" ), \
     130        ( (v1) ^ (v2) ) \
     131    )
     132
    90133#endif
    91 #define ORIGIN_TAG_MASK (((size_t)1) << ORIGIN_TAG_BITNO)
    92 
    93 #define ORIGIN_TAG_SET( p )   ((p) |  ORIGIN_TAG_MASK)
    94 #define ORIGIN_TAG_CLEAR( p ) ((p) & ~ORIGIN_TAG_MASK)
    95 #define ORIGIN_TAG_QUERY( p ) ((p) &  ORIGIN_TAG_MASK)
     134
     135
     136
     137#ifdef __EXPERIMENTAL_LOOSE_SINGLES__ // Perf experimention alt mode
     138
     139    // In loose-singles mode, the ability to answer an "is listed" query is disabled, as is "to insert an element,
     140    // it must not be listed already" checking.  The user must know separately whether an element is listed.
     141    // Other than inserting it, any list-api action on an unlisted element is undefined.  Notably, list iteration
     142    // starting from an unlisted element is not defined to respond "no more elements," and may instead continue
     143    // iterating from a formerly occupied list position.  This mode matches LQ usage.
     144
     145    #define NOLOOSE(...)
     146    #define LOOSEONLY(...) __VA_ARGS__
     147
     148#else // Normal
     149
     150    #define NOLOOSE(...) __VA_ARGS__
     151    #define LOOSEONLY(...)
     152
     153#endif
     154
     155
     156
     157
    96158
    97159forall( tE & ) {
     
    102164
    103165        static inline void ?{}( dlink( tE ) & this ) {
     166          NOLOOSE(
    104167                this.next = this.prev = 0p;
     168          )
    105169        }
    106170
     
    129193static inline forall( tE &, tLinks & | embedded( tE, tLinks, dlink( tE ) ) ) {
    130194        bool isListed( tE & node ) {
     195      NOLOOSE(
    131196                verify( &node != 0p );
    132197                dlink( tE ) & node_links = node`inner;
    133198                return (node_links.prev != 0p) || (node_links.next != 0p);
     199          )
     200          LOOSEONLY(
     201        verify(false && "isListed is undefined");
     202                return true;
     203          )
    134204        }
    135205
     
    157227
    158228                dlink( tE ) & linkToInsert = node`inner;
    159 
     229      NOLOOSE(
    160230                verify( linkToInsert.next == 0p );
    161231                verify( linkToInsert.prev == 0p );
     232          )
    162233
    163234                tE & list_pos_elem = *(tE *)ORIGIN_TAG_CLEAR( (size_t)&before );
     
    180251
    181252                dlink( tE ) & linkToInsert = node`inner;
    182 
     253      NOLOOSE(
    183254                verify( linkToInsert.prev == 0p );
    184255                verify( linkToInsert.next == 0p );
     256          )
    185257
    186258                tE & list_pos_elem = *(tE *)ORIGIN_TAG_CLEAR( (size_t)&after );
     
    211283                before_links.next = &after_raw;
    212284                after_links.prev = &before_raw;
     285
     286      NOLOOSE(
    213287                asm( "" : : : "memory" );
    214288                list_pos_links.prev = 0p;
    215289                list_pos_links.next = 0p;
    216290                asm( "" : : : "memory" );
     291          )
    217292                return node;
    218293        }
  • libcfa/src/stdhdr/assert.h

    r7640ff5 r7806f91  
    3838        #define warnf( expr, fmt, ... ) ({ static bool check_once##__LINE__ = false; if( false == check_once##__LINE__ && false == (expr)) { check_once##__LINE__ = true; __assert_warn_f(__VSTRINGIFY__(expr), __FILE__, __LINE__, __PRETTY_FUNCTION__, fmt, ## __VA_ARGS__ ); } })
    3939#else
    40         #define verify(x)
    41         #define verifyf(x, ...)
    42         #define verifyfail(...)
    43         #define warnf( expr, fmt, ... )
     40        #define verify(x) 0
     41        #define verifyf(x, ...) 0
     42        #define verifyfail(...) 0
     43        #define warnf( expr, fmt, ... ) 0
    4444#endif
    4545
Note: See TracChangeset for help on using the changeset viewer.