From fd0bca1d91ca0ed6fa093c05fd9925847b39b197 Mon Sep 17 00:00:00 2001 From: Adam Edward Barton <adam.edward.barton@cern.ch> Date: Fri, 5 Jun 2020 19:55:24 +0000 Subject: [PATCH] Adjust idc for faster filling ATLASRECTS-5521 --- .../EventContainers/InternalOfflineFast.h | 7 ++- .../src/InternalOfflineFast.cxx | 43 ++++++++++--------- Event/EventContainers/test/IDC_Benchmark.cxx | 23 ++++++++++ 3 files changed, 51 insertions(+), 22 deletions(-) diff --git a/Event/EventContainers/EventContainers/InternalOfflineFast.h b/Event/EventContainers/EventContainers/InternalOfflineFast.h index 8f247efefa1..b32569e83ee 100644 --- a/Event/EventContainers/EventContainers/InternalOfflineFast.h +++ b/Event/EventContainers/EventContainers/InternalOfflineFast.h @@ -5,6 +5,9 @@ #ifndef EVENTCONTAINERS_INTERNALOFFLINEFAST_H #define EVENTCONTAINERS_INTERNALOFFLINEFAST_H #include "EventContainers/I_InternalIDC.h" +#include "CxxUtils/checker_macros.h" +#include <atomic> +#include <mutex> namespace EventContainers{ /* @@ -21,8 +24,10 @@ public: virtual InternalConstItr cend() const override; virtual InternalConstItr indexFind( IdentifierHash hashId ) const override; virtual const std::vector < hashPair >& getAllHashPtrPair() const override; - std::vector<std::pair<IdentifierHash::value_type, const void*>> m_map; + mutable std::vector<std::pair<IdentifierHash::value_type, const void*>> m_map; std::vector<const void*> m_fullMap; + mutable std::mutex m_waitMutex ATLAS_THREAD_SAFE; + mutable std::atomic<bool> m_needsupdate ATLAS_THREAD_SAFE; //These mutables are carefully thought out, do not change virtual bool tryAddFromCache(IdentifierHash hashId, EventContainers::IDC_WriteHandleBase &lock) override; virtual bool tryAddFromCache(IdentifierHash hashId) override; virtual void wait() const override; diff --git a/Event/EventContainers/src/InternalOfflineFast.cxx b/Event/EventContainers/src/InternalOfflineFast.cxx index 3cdb1a16327..d3a799015a1 100644 --- a/Event/EventContainers/src/InternalOfflineFast.cxx +++ b/Event/EventContainers/src/InternalOfflineFast.cxx @@ -8,7 +8,7 @@ using namespace EventContainers; typedef I_InternalIDC::InternalConstItr InternalConstItr; -InternalOfflineFast::InternalOfflineFast(size_t max) : m_fullMap(max, nullptr) {} +InternalOfflineFast::InternalOfflineFast(size_t max) : m_fullMap(max, nullptr), m_needsupdate(false) {} bool InternalOfflineFast::tryAddFromCache(IdentifierHash hash, EventContainers::IDC_WriteHandleBase&) { @@ -21,10 +21,17 @@ bool InternalOfflineFast::tryAddFromCache(IdentifierHash hash) } void InternalOfflineFast::wait() const { - + std::lock_guard lock (m_waitMutex); + if(m_needsupdate == false) return; + m_map.clear(); + for(size_t i=0 ;i < m_fullMap.size(); ++i){ + if(m_fullMap[i]) m_map.emplace_back(i, m_fullMap[i]); + } + m_needsupdate.store(true); } std::vector<IdentifierHash> InternalOfflineFast::getAllCurrentHashes() const { + if(m_needsupdate) wait(); std::vector<IdentifierHash> ids; ids.reserve(m_map.size()); for(auto &x : m_map) { @@ -35,24 +42,30 @@ std::vector<IdentifierHash> InternalOfflineFast::getAllCurrentHashes() const { InternalConstItr InternalOfflineFast::cend() const { + if(m_needsupdate) wait(); return m_map.cend(); } -const std::vector < I_InternalIDC::hashPair >& InternalOfflineFast::getAllHashPtrPair() const{ return m_map; } +const std::vector < I_InternalIDC::hashPair >& InternalOfflineFast::getAllHashPtrPair() const{ + if(m_needsupdate) wait(); + return m_map; +} InternalConstItr InternalOfflineFast::cbegin() const { + if(m_needsupdate) wait(); return m_map.cbegin(); } InternalConstItr InternalOfflineFast::indexFind( IdentifierHash hashId ) const{ + if(m_needsupdate) wait(); auto itr = std::lower_bound( m_map.cbegin(), m_map.cend(), hashId.value(), [](const hashPair &lhs, IdentifierHash::value_type rhs) -> bool { return lhs.first < rhs; } ); if(itr!= m_map.cend() && itr->first==hashId) return itr; return m_map.cend(); -// return std::find_if(m_map.begin(), m_map.end(), [hashId](const hashPair &lhs) -> bool { return lhs.first == hashId; }); } size_t InternalOfflineFast::numberOfCollections() const { + if(m_needsupdate) wait(); return m_map.size(); } @@ -64,19 +77,9 @@ void InternalOfflineFast::cleanUp(deleter_f* deleter) noexcept { bool InternalOfflineFast::insert(IdentifierHash hashId, const void* ptr) { if(hashId >= m_fullMap.size()) return false; if(m_fullMap[hashId]!= nullptr) return false; //already in - if(m_map.empty() || m_map.back().first < hashId){ - m_map.emplace_back(hashId, ptr); - m_fullMap[hashId] = ptr; - return true; - } - auto itr = std::lower_bound( m_map.begin(), m_map.end(), hashId.value(), [](const hashPair &lhs, IdentifierHash::value_type rhs) -> bool { return lhs.first < rhs; } ); - if(itr == std::end(m_map) || itr->first != hashId) - { - m_map.emplace(itr, hashId, ptr); - m_fullMap[hashId] = ptr; - return true; - } - return false; + m_fullMap[hashId] = ptr; + m_needsupdate.store(true, std::memory_order_relaxed); + return true; } const void* InternalOfflineFast::findIndexPtr(IdentifierHash hashId) const noexcept{ @@ -96,11 +99,9 @@ StatusCode InternalOfflineFast::addLock(IdentifierHash hashId, const void* ptr) } void* InternalOfflineFast::removeCollection( IdentifierHash hashId ) { - auto itr = std::lower_bound( m_map.begin(), m_map.end(), hashId.value(), [](hashPair &lhs, IdentifierHash::value_type rhs) -> bool { return lhs.first < rhs; } ); - if(itr== m_map.end() || itr->first!=hashId) return nullptr; - void* ptr = const_cast< void* > (itr->second); - m_map.erase(itr); + void* ptr = const_cast< void* > (m_fullMap[hashId]); m_fullMap[hashId] = nullptr; + m_needsupdate.store(true, std::memory_order_relaxed); return ptr; } diff --git a/Event/EventContainers/test/IDC_Benchmark.cxx b/Event/EventContainers/test/IDC_Benchmark.cxx index 806359c8259..6e7b9bfddfe 100644 --- a/Event/EventContainers/test/IDC_Benchmark.cxx +++ b/Event/EventContainers/test/IDC_Benchmark.cxx @@ -17,6 +17,17 @@ void timedelete(std::string name, T* ptr){ std::cout << name << " delete time " << time.count() << std::endl; } +void timebackwardsfill(std::string name, IdentifiableContainerMT<long unsigned int> *ptr){ + auto start1 = std::chrono::steady_clock::now(); + for(size_t i =50000-2;i>=3;i-=3){ + ptr->addCollection(new long unsigned int(i) ,i).ignore(); + } + auto end1 = std::chrono::steady_clock::now(); + std::chrono::duration<double> time = end1-start1; + std::cout << name << " backwardsfill time " << time.count() << std::endl; +} + + void accessTime(std::string name, IdentifiableContainerMT<long unsigned int>& container){ auto start3 = std::chrono::steady_clock::now(); @@ -77,6 +88,18 @@ int main(){ timedelete("onlineCache ", cache); timedelete("offline ", offline); timedelete("offlinefast ", offlinefast); + + auto offlinefast2 = new IdentifiableContainerMT<long unsigned int>(50000, EventContainers::Mode::OfflineFast); + auto cache2 = new IdentifiableCache<long unsigned int>(50000, nullptr); + auto online2 = new IdentifiableContainerMT<long unsigned int>(cache2); + auto offline2 = new IdentifiableContainerMT<long unsigned int>(50000); + timebackwardsfill("offlinefast", offlinefast2); + timebackwardsfill("offline", offline2); + timebackwardsfill("online", online2); + delete offline2; + delete online2; + delete cache2; + delete offlinefast2; std::cout << "Test Successful" << std::endl; return 0; } -- GitLab