Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #9135 from mark-grimes/guessCollectionSizes
Backport RunningAverage and use for PFRecHitProducer reserve
- Loading branch information
Showing
5 changed files
with
124 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
#ifndef FWCore_Utilities_RunningAverage_H | ||
#define FWCore_Utilities_RunningAverage_H | ||
#include <atomic> | ||
#include <algorithm> | ||
#include <array> | ||
|
||
namespace edm { | ||
// keeps the running average of the last N entries | ||
// thread safe, fast: does not garantee precise update in case of collision | ||
class RunningAverage { | ||
public: | ||
static constexpr int N = 16; // better be a power of 2 | ||
explicit RunningAverage(unsigned int k=4) : m_mean(N*k), m_curr(0) { | ||
for (auto & i : m_buffer) i=k; | ||
} | ||
|
||
int mean() const { return m_mean/N;} | ||
|
||
int upper() const { auto lm = mean(); return lm+=(std::abs(m_buffer[0]-lm)+std::abs(m_buffer[N/2]-lm)); } // about 2 sigma | ||
|
||
void update(unsigned int q) { | ||
int e=m_curr; | ||
while(!m_curr.compare_exchange_weak(e,e+1)); | ||
int k = (N-1)&e; | ||
int old = m_buffer[k]; | ||
if (!m_buffer[k].compare_exchange_strong(old,q)) return; | ||
m_mean+= (q-old); | ||
} | ||
|
||
|
||
private: | ||
std::array<std::atomic<int>,N> m_buffer; | ||
std::atomic<int> m_mean; | ||
std::atomic<int> m_curr; | ||
|
||
}; | ||
} | ||
|
||
#endif | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -42,3 +42,7 @@ | |
</bin> | ||
<bin file="EDGetToken_t.cpp"> | ||
</bin> | ||
|
||
<bin file="RunningAverage_t.cpp"> | ||
<use name="tbb"/> | ||
</bin> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
#define private public | ||
#include "FWCore/Utilities/interface/RunningAverage.h" | ||
#undef private | ||
|
||
namespace { | ||
|
||
edm::RunningAverage localRA; | ||
|
||
} | ||
|
||
#include "tbb/parallel_for.h" | ||
#include "tbb/task_scheduler_init.h" | ||
#include <iostream> | ||
#include <vector> | ||
#include <atomic> | ||
#include <random> | ||
#include <algorithm> | ||
#include <type_traits> | ||
|
||
int main() { | ||
|
||
|
||
//tbb::task_scheduler_init init; // Automatic number of threads | ||
tbb::task_scheduler_init init(tbb::task_scheduler_init::default_num_threads()); // Explicit number of threads | ||
|
||
// std::random_device rd; | ||
std::mt19937 e2; // (rd()); | ||
std::normal_distribution<> normal_dist(1000., 200.); | ||
|
||
|
||
|
||
int kk=0; | ||
|
||
|
||
int n=2000; | ||
|
||
int res[n]; | ||
int qq[n]; for (auto & y:qq) y = std::max(0.,normal_dist(e2)); | ||
|
||
auto theLoop = [&](int i, std::vector<float>& v ) { | ||
kk++; | ||
v.reserve(res[i]=localRA.upper()); | ||
v.resize(qq[i]); | ||
localRA.update(v.size()); | ||
std::vector<float> t; | ||
swap(v,t); | ||
}; | ||
|
||
|
||
tbb::parallel_for( | ||
tbb::blocked_range<size_t>(0,n), | ||
[&](const tbb::blocked_range<size_t>& r) { | ||
std::vector<float> v; // Had to move this declaration here because there's no thread_local in this version of gcc (in 7_5_X it's declared above) | ||
for (size_t i=r.begin();i<r.end();++i) theLoop(i,v); | ||
} | ||
); | ||
|
||
|
||
auto mm = std::max_element(res,res+n); | ||
std::cout << kk << ' ' << localRA.m_curr << ' ' << localRA.mean() << std::endl; | ||
for (auto & i : localRA.m_buffer) std::cout << i << ' '; | ||
std::cout << std::endl; | ||
std::cout << std::accumulate(res,res+n,0)/n | ||
<< ' ' << *std::min_element(res+16,res+n) << ',' << *mm << std::endl; | ||
|
||
return 0; | ||
|
||
|
||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters