Boost multi-thread issue ---- use macro

Why #if ISTHREADSAFE boost::mutex::scoped_lock lock(CacheInfo_mutex); # endif functions well , but not if(isThreadSafe) { boost::mutex::scoped_lock lock(CacheInfo_mutex); } -- Peisheng Wang Software Engineer iZENEsoft (Shanghai) Co., Ltd Room 601 Marine Tower, No. 1 Pudong Ave. Tel:86-21-68860698-114 Fax:86-21-68860699 Company Website:<a target="_blank" href="http://www.izenesoft.com/">www.izenesoft.com</a> <a href="../../../../index.php?menuaction=felamimail.uicompose.compose&send_to=Wmhlbi5ZdUBNb3JnYW5TdGFubGV5LmNvbQ==">Zhen.Yu@MorganStanley.com</a>

On 5/14/08, Peisheng Wang
Why
#if ISTHREADSAFE boost::mutex::scoped_lock lock(CacheInfo_mutex); # endif
functions well , but not
if(isThreadSafe) { boost::mutex::scoped_lock lock(CacheInfo_mutex); }
The valriable 'lock' is created in the local scope and will get destroyed once you are out of the 'if' scope. Also, use of macros for things that do not change at runtime is better as it avoids the runtime overhead of performing the check. -dky -- Contents reflect my personal views only!

Peisheng Wang wrote:
Why
#if ISTHREADSAFE boost::mutex::scoped_lock lock(CacheInfo_mutex); # endif
functions well , but not
if(isThreadSafe) { boost::mutex::scoped_lock lock(CacheInfo_mutex); }
Because the scoped_lock declaration goes out of scope at the }. If you had written: #if ISTHREADSAFE { boost::mutex::scoped_lock lock(CacheInfo_mutex); } # endif it would have the same problem.

A general question about its capabilities. The library is excellent for getting updated statistics as one adds values to an accumulator. I have one wrinkle. I have long running time series, and wish to evaluate statistics on a window of the data, say the last 100 values. Can the Accumulator framework be used in a 'windowed' situation? For example, for a similar smaller scale project, I used a queue ( to represent a specific time frame) to to keep track of a series of values. As values are added to the queue, they are added into a statistic. As the values are dropped from the qeue, the values are removed from a statistic. I understand that rounding errors may accumulate over time, but current experiments indicate that the error magnitude by the end of the series is not noticable. If code helps to make sense, here is what I did on a smaller scale with simple statistics (some may comment on the lack of getters and setters, but at least the concept is there): class CRunningStats { public: CRunningStats(void); CRunningStats(double BBMultiplier); virtual ~CRunningStats(void); void SetBBMultiplier( double dbl ) { m_BBMultiplier = dbl; }; double GetBBMultiplier( void ) { return m_BBMultiplier; }; double b2; // acceleration double b1; // slope double b0; // offset double meanY; double RR; double R; double SD; double BBUpper, BBLower; void Add( double, double ); void Remove( double, double ); virtual void CalcStats( void ); protected: unsigned int nX, nY; double SumXX, SumX, SumXY, SumY, SumYY; double Sxx, Sxy, Syy; double SST, SSR, SSE; double m_BBMultiplier; private: }; CRunningStats::CRunningStats(void) : b2( 0 ), b1( 0 ), b0( 0 ), SumXX( 0 ), SumX( 0 ), SumXY( 0 ), SumY( 0 ), SumYY( 0 ), nX( 0 ), m_BBMultiplier( 2.0 ) { } CRunningStats::CRunningStats( double BBMultiplier ) : b2( 0 ), b1( 0 ), b0( 0 ), SumXX( 0 ), SumX( 0 ), SumXY( 0 ), SumY( 0 ), SumYY( 0 ), nX( 0 ), m_BBMultiplier( BBMultiplier ) { } CRunningStats::~CRunningStats(void) { } void CRunningStats::Add(double x, double y) { SumXX += x * x; SumX += x; SumXY += x * y; SumY += y; SumYY += y * y; nX++; } void CRunningStats::Remove(double x, double y) { SumXX -= x * x; SumX -= x; SumXY -= x * y; SumY -= y; SumYY -= y * y; nX--; } void CRunningStats::CalcStats() { if ( nX > 1 ) { double oldb1 = b1; Sxx = SumXX - ( SumX * SumX ) / nX; Sxy = SumXY - ( SumX * SumY ) / nX; Syy = SumYY - ( SumY * SumY ) / nX; SST = Syy; SSR = ( Sxy * Sxy ) / Sxx; SSE = SST - SSR; RR = SSR / SST; R = Sxy / sqrt(Sxx * Syy); //SD = Math.Sqrt(Syy / (Xcnt - 1)); SD = sqrt(Syy / nX); meanY = SumY / nX; double BBOffset = m_BBMultiplier * SD; BBUpper = meanY + BBOffset; BBLower = meanY - BBOffset; b1 = ( nX > 1 ) ? Sxy / Sxx : 0; b0 = (1 / nX) * ( SumY - b1 * SumX ); b2 = b1 - oldb1; // *** do this differently } } -- Scanned for viruses and dangerous content at http://www.oneunified.net and is believed to be clean.

Ray Burkholder wrote:
A general question about its capabilities. The library is excellent for getting updated statistics as one adds values to an accumulator.
I have one wrinkle. I have long running time series, and wish to evaluate statistics on a window of the data, say the last 100 values. Can the Accumulator framework be used in a 'windowed' situation?
It can, but you would have to code up such a windowing accumulator yourself. The docs show how to extend the accumulators framework. An accumulator like a rolling average is non-trivial, though. I once wrote a rolling average function object for use with the Boost.Time_series library. It uses boost::circular_buffer to store the last N elements. You would need to do a bit of work to adapt this for use with the accumulators library, but the logic is there for the taking. You can find it here: http://lists.boost.org/Archives/boost/2007/07/124979.php -- Eric Niebler Boost Consulting www.boost-consulting.com
participants (5)
-
dhruva
-
Eric Niebler
-
Nat Goodspeed
-
Peisheng Wang
-
Ray Burkholder