Ignore:
Timestamp:
Aug 11, 2020, 4:40:15 PM (5 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
0d070ca
Parents:
07d867b (diff), 129674b (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' into new-ast

File:
1 edited

Legend:

Unmodified
Added
Removed
  • doc/theses/thierry_delisle_PhD/code/utils.hpp

    r07d867b r22f94a4  
    3535};
    3636
     37// class Random {
     38// private:
     39//      unsigned int seed;
     40// public:
     41//      Random(int seed) {
     42//              this->seed = seed;
     43//      }
     44
     45//      /** returns pseudorandom x satisfying 0 <= x < n. **/
     46//      unsigned int next() {
     47//              seed ^= seed << 6;
     48//              seed ^= seed >> 21;
     49//              seed ^= seed << 7;
     50//              return seed;
     51//      }
     52// };
     53
     54constexpr uint64_t extendedEuclidY(uint64_t a, uint64_t b);
     55constexpr uint64_t extendedEuclidX(uint64_t a, uint64_t b){
     56    return (b==0) ? 1 : extendedEuclidY(b, a - b * (a / b));
     57}
     58constexpr uint64_t extendedEuclidY(uint64_t a, uint64_t b){
     59    return (b==0) ? 0 : extendedEuclidX(b, a - b * (a / b)) - (a / b) * extendedEuclidY(b, a - b * (a / b));
     60}
     61
    3762class Random {
    3863private:
    39         unsigned int seed;
     64        uint64_t x;
     65
     66        static constexpr const uint64_t M  = 1ul << 48ul;
     67        static constexpr const uint64_t A  = 25214903917;
     68        static constexpr const uint64_t C  = 11;
     69        static constexpr const uint64_t D  = 16;
     70
    4071public:
    41         Random(int seed) {
    42                 this->seed = seed;
     72        static constexpr const uint64_t m  = M;
     73        static constexpr const uint64_t a  = A;
     74        static constexpr const uint64_t c  = C;
     75        static constexpr const uint64_t d  = D;
     76        static constexpr const uint64_t ai = extendedEuclidX(A, M);
     77public:
     78        Random(unsigned int seed) {
     79                this->x = seed * a;
    4380        }
    4481
    4582        /** returns pseudorandom x satisfying 0 <= x < n. **/
    4683        unsigned int next() {
    47                 seed ^= seed << 6;
    48                 seed ^= seed >> 21;
    49                 seed ^= seed << 7;
    50                 return seed;
    51         }
     84                //nextx = (a * x + c) % m;
     85                x = (A * x + C) & (M - 1);
     86                return x >> D;
     87        }
     88        unsigned int prev() {
     89                //prevx = (ainverse * (x - c)) mod m
     90                unsigned int r = x >> D;
     91                x = ai * (x - C) & (M - 1);
     92                return r;
     93        }
     94
     95        void set_raw_state(uint64_t _x) {
     96                this->x = _x;
     97        }
     98
     99        uint64_t get_raw_state() {
     100                return this->x;
     101        }
    52102};
    53103
     
    106156}
    107157
     158static inline unsigned rand_bit(unsigned rnum, size_t mask) __attribute__((artificial));
    108159static inline unsigned rand_bit(unsigned rnum, size_t mask) {
    109160        unsigned bit = mask ? rnum % __builtin_popcountl(mask) : 0;
     
    143194#endif
    144195}
     196
     197struct spinlock_t {
     198        std::atomic_bool ll = { false };
     199
     200        inline void lock() {
     201                while( __builtin_expect(ll.exchange(true),false) ) {
     202                        while(ll.load(std::memory_order_relaxed))
     203                                asm volatile("pause");
     204                }
     205        }
     206
     207        inline bool try_lock() {
     208                return false == ll.exchange(true);
     209        }
     210
     211        inline void unlock() {
     212                ll.store(false, std::memory_order_release);
     213        }
     214
     215        inline explicit operator bool() {
     216                return ll.load(std::memory_order_relaxed);
     217        }
     218};
     219
     220static inline bool bts(std::atomic_size_t & target, size_t bit ) {
     221        //*
     222        int result = 0;
     223        asm volatile(
     224                "LOCK btsq %[bit], %[target]\n\t"
     225                :"=@ccc" (result)
     226                : [target] "m" (target), [bit] "r" (bit)
     227        );
     228        return result != 0;
     229        /*/
     230        size_t mask = 1ul << bit;
     231        size_t ret = target.fetch_or(mask, std::memory_order_relaxed);
     232        return (ret & mask) != 0;
     233        //*/
     234}
     235
     236static inline bool btr(std::atomic_size_t & target, size_t bit ) {
     237        //*
     238        int result = 0;
     239        asm volatile(
     240                "LOCK btrq %[bit], %[target]\n\t"
     241                :"=@ccc" (result)
     242                : [target] "m" (target), [bit] "r" (bit)
     243        );
     244        return result != 0;
     245        /*/
     246        size_t mask = 1ul << bit;
     247        size_t ret = target.fetch_and(~mask, std::memory_order_relaxed);
     248        return (ret & mask) != 0;
     249        //*/
     250}
Note: See TracChangeset for help on using the changeset viewer.