diff options
author | Anthony Barbier <anthony.barbier@arm.com> | 2018-07-03 16:22:02 +0100 |
---|---|---|
committer | Anthony Barbier <anthony.barbier@arm.com> | 2018-11-02 16:54:10 +0000 |
commit | 5f707736413aeac77818c42838296966f8dc6761 (patch) | |
tree | b829ed3243ea5f3085f288836132416c78bc2e72 /src/core/NEON/kernels/arm_gemm/buffer_manager.hpp | |
parent | 7485d5a62685cb745ab50e970adb722cb71557ac (diff) | |
download | ComputeLibrary-5f707736413aeac77818c42838296966f8dc6761.tar.gz |
COMPMID-1369: Revert accidental formatting of RSH's repo
Pulled latest fixes from David's repo:
commit f43ebe932c84083332b0b1a0348241b69dda63a7
Author: David Mansell <David.Mansell@arm.com>
Date: Tue Jul 3 18:09:01 2018 +0100
Whitespace tidying, fixed comment in gemv_batched imported from ACL.
Change-Id: Ie37a623f44e90d88072236cb853ac55ac82d5f51
Reviewed-on: https://eu-gerrit-1.euhpc.arm.com/138530
Tested-by: Jenkins <bsgcomp@arm.com>
Reviewed-by: Georgios Pinitas <georgios.pinitas@arm.com>
Reviewed-by: Gian Marco Iodice <gianmarco.iodice@arm.com>
Reviewed-by: David Mansell <david.mansell@arm.com>
Reviewed-by: Anthony Barbier <anthony.barbier@arm.com>
Diffstat (limited to 'src/core/NEON/kernels/arm_gemm/buffer_manager.hpp')
-rw-r--r-- | src/core/NEON/kernels/arm_gemm/buffer_manager.hpp | 198 |
1 files changed, 75 insertions, 123 deletions
diff --git a/src/core/NEON/kernels/arm_gemm/buffer_manager.hpp b/src/core/NEON/kernels/arm_gemm/buffer_manager.hpp index dd74744ebc..03f099d57b 100644 --- a/src/core/NEON/kernels/arm_gemm/buffer_manager.hpp +++ b/src/core/NEON/kernels/arm_gemm/buffer_manager.hpp @@ -38,36 +38,33 @@ #endif -namespace arm_gemm -{ +namespace arm_gemm { + #ifndef NO_MULTI_THREADING -enum class BufferStatus -{ +enum class BufferStatus { IDLE, POPULATING, BUSY }; -class Buffer -{ +class Buffer { private: - const int _maxusers; // Maximum permissible threads. - void *const _storage; // Storage for buffer content. + const int _maxusers; // Maximum permissible threads. + void * const _storage; // Storage for buffer content. - int _numusers; // Actual number of threads (might be lower). + int _numusers; // Actual number of threads (might be lower). - volatile BufferStatus _status = BufferStatus::IDLE; // Status - std::atomic_int _users = {}; // How many users are still using the buffer. - volatile int _index = 0; // Which block of data currently resides in the buffer. + volatile BufferStatus _status = BufferStatus::IDLE; // Status + std::atomic_int _users = { }; // How many users are still using the buffer. + volatile int _index = 0; // Which block of data currently resides in the buffer. - std::mutex _lock = {}; + std::mutex _lock = { }; #ifdef USE_SEMAPHORE - std::condition_variable _cv = {}; + std::condition_variable _cv = { }; #endif template <typename T> - void populate_buffer(T func) - { + void populate_buffer(T func) { func(_storage); /* Now mark it as ready. */ @@ -78,17 +75,15 @@ private: _cv.notify_all(); } #else - _status = BufferStatus::BUSY; + _status = BufferStatus::BUSY; #endif } public: Buffer(Buffer &) = delete; - Buffer &operator=(Buffer &) = delete; + Buffer &operator= (Buffer &) = delete; - Buffer(void *storage, int maxusers) - : _maxusers(maxusers), _storage(storage), _numusers(maxusers) - { + Buffer(void *storage, int maxusers) : _maxusers(maxusers), _storage(storage), _numusers(maxusers) { _status = BufferStatus::IDLE; } @@ -99,38 +94,32 @@ public: * If it's already being populated by another thread or is ready, return. */ template <typename T> - void try_populate(const int index, T func) - { - for(;;) - { + void try_populate(const int index, T func) { + for (;;) { #ifdef USE_SEMAPHORE /* If it's busy with a previous index, wait on the semaphore. */ - if((_status == BufferStatus::BUSY) && (_index != index)) - { + if ((_status == BufferStatus::BUSY) && (_index != index)) { std::unique_lock<std::mutex> ul(_lock); - if((_status == BufferStatus::BUSY) && (_index != index)) - { + if ((_status == BufferStatus::BUSY) && (_index != index)) { _cv.wait(ul); } } #endif /* Return if another thread is populating it already. */ - if((_index == index) && ((_status == BufferStatus::POPULATING) || (_status == BufferStatus::BUSY))) - { + if ((_index == index) && + ((_status == BufferStatus::POPULATING) || (_status == BufferStatus::BUSY))) { return; } - if(_status == BufferStatus::IDLE) - { + if (_status == BufferStatus::IDLE) { std::lock_guard<std::mutex> guard(_lock); /* If the buffer is still idle, we can grab it and populate it. */ - if(_status == BufferStatus::IDLE) - { + if (_status == BufferStatus::IDLE) { _status = BufferStatus::POPULATING; - _index = index; - _users = _numusers; + _index = index; + _users = _numusers; break; } } @@ -141,26 +130,26 @@ public: } template <typename T> - void *get(const int index, T func) - { + void *get(const int index, T func) { // Loop until we achieve something. - for(;;) - { + for (;;) { // If the index is correct and the buffer status is busy then we can // just return the content. No locking is needed here as the index // cannot change (and status cannot change from BUSY) until all // users have finished. - if((_index == index) && (_status == BufferStatus::BUSY)) - { + if ((_index == index) && (_status == BufferStatus::BUSY)) { return _storage; } + + /* If the buffer still has some previous content, or is being + * populated, we can wait with the semaphore. */ #ifdef USE_SEMAPHORE - if(((_status == BufferStatus::BUSY) && (_index != index)) || (_status == BufferStatus::POPULATING)) - { + if (((_status == BufferStatus::BUSY) && (_index != index)) || + (_status == BufferStatus::POPULATING)) { std::unique_lock<std::mutex> ul(_lock); - if(((_status == BufferStatus::BUSY) && (_index != index)) || (_status == BufferStatus::POPULATING)) - { + if (((_status == BufferStatus::BUSY) && (_index != index)) || + (_status == BufferStatus::POPULATING)) { _cv.wait(ul); } } @@ -168,17 +157,15 @@ public: // If it's idle, we need to populate it. The IDLE->POPULATING // transition requires the lock. - if(_status == BufferStatus::IDLE) - { + if (_status == BufferStatus::IDLE) { std::lock_guard<std::mutex> guard(_lock); /* If it's still idle, grab it. Otherwise drop through and * we'll do something else next time through the loop. */ - if(_status == BufferStatus::IDLE) - { + if (_status == BufferStatus::IDLE) { _status = BufferStatus::POPULATING; - _index = index; - _users = _numusers; + _index = index; + _users = _numusers; break; } } @@ -194,10 +181,8 @@ public: * simply (atomically) decrement the user count, and if it's hit zero we * flag the buffer as idle. */ - void release(void) - { - if(--_users == 0) - { + void release(void) { + if (--_users == 0) { #ifdef USE_SEMAPHORE std::unique_lock<std::mutex> ul(_lock); _status = BufferStatus::IDLE; @@ -211,110 +196,91 @@ public: } /* This is called to change the number of users. */ - void set_numusers(int numusers) - { + void set_numusers(int numusers) { _numusers = std::min(numusers, _maxusers); } }; -class BufferManager -{ + +class BufferManager { private: /* This has to be a vector of Buffer *, because a Buffer cannot be moved * or copied due to atomic members. */ - std::vector<Buffer *> _buffers = {}; - const int _maxthreads; - void *const _storage; + std::vector<Buffer *> _buffers = { }; + const int _maxthreads; + void * const _storage; public: BufferManager(BufferManager &) = delete; - BufferManager &operator=(BufferManager &) = delete; + BufferManager & operator=(BufferManager &) = delete; // Say how much storage is needed. - static inline size_t get_storage_requirement(const int maxthreads, const size_t buffersize) - { + static inline size_t get_storage_requirement(const int maxthreads, const size_t buffersize) { return buffersize * ((maxthreads == 1) ? 1 : 3); } - BufferManager(const int maxthreads, const size_t buffersize, void *storage) - : _maxthreads(maxthreads), _storage(storage) - { + BufferManager(const int maxthreads, const size_t buffersize, void *storage) : _maxthreads(maxthreads), _storage(storage) { const int numbuffers = (maxthreads == 1) ? 1 : 3; /* We don't need any Buffer objects in single thread mode. */ - if(_maxthreads == 1) - { + if (_maxthreads == 1) { return; } /* Use intptr_t to avoid performing arithmetic on a void * */ intptr_t storage_int = reinterpret_cast<intptr_t>(_storage); - for(int i = 0; i < numbuffers; i++) - { + for (int i=0; i<numbuffers; i++) { _buffers.push_back(new Buffer(reinterpret_cast<void *>(storage_int), _maxthreads)); storage_int += buffersize; } } - ~BufferManager() - { - while(_buffers.size()) - { + ~BufferManager() { + while (_buffers.size()) { delete _buffers.back(); _buffers.pop_back(); } } template <typename T> - void *get(const int index, T func) - { + void *get(const int index, T func) { /* In single thread mode, we just directly call the populating * function on the (single) buffer, otherwise forward to the * relevant Buffer. */ - if(_maxthreads == 1) - { + if (_maxthreads==1) { func(_storage); return _storage; - } - else - { + } else { return _buffers[index % _buffers.size()]->get(index, func); } } template <typename T> - void try_populate(const int index, T func) - { + void try_populate(const int index, T func) { /* No need for this in single thread mode. */ - if(_maxthreads == 1) - { + if (_maxthreads==1) { return; } _buffers[index % _buffers.size()]->try_populate(index, func); } - void release(const int index) - { + void release(const int index) { /* No need for this in single thread mode. */ - if(_maxthreads == 1) - { + if (_maxthreads==1) { return; } _buffers[index % _buffers.size()]->release(); } - void set_nthreads(int threads) - { - if(_maxthreads == 1) - { + void set_nthreads(int threads) { + if (_maxthreads==1) { return; } - for(unsigned int i = 0; i < _buffers.size(); i++) - { + for(unsigned int i=0; i<_buffers.size(); i++) { _buffers[i]->set_numusers(threads); } } @@ -329,49 +295,35 @@ public: * All the other methods do nothing. */ -class BufferManager -{ +class BufferManager { private: - void *const _storage; + void * const _storage; public: BufferManager(BufferManager &) = delete; - BufferManager &operator=(BufferManager &) = delete; + BufferManager & operator=(BufferManager &) = delete; - BufferManager(const int maxthreads, const size_t buffersize, void *storage) - : _storage(storage) - { - } + BufferManager(const int maxthreads, const size_t buffersize, void *storage) : _storage(storage) { } - ~BufferManager() - { - } + ~BufferManager() { } // Say how much storage is needed. - static inline size_t get_storage_requirement(const int maxthreads, const size_t buffersize) - { + static inline size_t get_storage_requirement(const int maxthreads, const size_t buffersize) { return buffersize; } template <typename T> - void try_populate(const int index, T func) - { - } + void try_populate(const int index, T func) { } - void release(const int index) - { - } + void release(const int index) { } template <typename T> - void *get(const int index, T func) - { + void *get(const int index, T func) { func(_storage); return _storage; } - void set_nthreads(int) - { - } + void set_nthreads(int) { } }; #endif |