Skip to content

Commit f7fdee2

Browse files
committed
SERVER-6572 use a thread local cache for better perforamnce in record caching
needs work on osx
1 parent c7d800c commit f7fdee2

File tree

1 file changed

+76
-2
lines changed

1 file changed

+76
-2
lines changed

src/mongo/db/record.cpp

Lines changed: 76 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,67 @@ namespace mongo {
202202
}
203203
}
204204

205+
/**
206+
* this acts a sort of lru bloom filter for records
207+
* if something is in it, the odds of it being in memory is exceedingly high (though not 100%)
208+
* if something is not in it, we have to do the more costly thread safe variant
209+
* this is also pseudo thread safe, meaning threads may stomp on each other
210+
* though the impact of that should be negligible, and the only risk falling back to the slow cachw
211+
* or in a bad case, not detecting a page fault
212+
*/
213+
class SimpleCache {
214+
public:
215+
/*
216+
SimpleCache() {
217+
_pos = 0;
218+
}
219+
*/
220+
bool inCache( size_t page ) const {
221+
for ( int i=0; i<SIZE; i++ )
222+
if ( _entries[i] == page )
223+
return true;
224+
return false;
225+
}
226+
227+
void add( size_t page ) {
228+
_entries[_pos++%SIZE] = page;
229+
}
230+
231+
static SimpleCache* get();
232+
233+
/*
234+
static SimpleCache* get() {
235+
#if 0
236+
unsigned long long id = 0;
237+
#ifdef _WIN32
238+
id = reinterpret_cast<unsigned long long>( GetCurrentThreadId() );
239+
#else
240+
id = static_cast<unsigned long long>(pthread_self());
241+
#endif
242+
return &_threaded[ id % NUM_THREADS ];
243+
}
244+
*/
245+
private:
246+
enum { SIZE = 25 };
247+
size_t _entries[SIZE];
248+
int _pos;
249+
250+
enum { NUM_THREADS = 128 };
251+
//static SimpleCache _threaded[NUM_THREADS];
252+
};
253+
254+
//SimpleCache SimpleCache::_threaded[NUM_THREADS];
255+
256+
#ifdef _WIN32
257+
__declspec( thread ) SimpleCache mySimpleCache;
258+
#else
259+
__thread SimpleCache mySimpleCache;
260+
#endif
261+
262+
SimpleCache* SimpleCache::get() {
263+
return &mySimpleCache;
264+
}
265+
205266
bool Record::MemoryTrackingEnabled = true;
206267

207268
volatile int __record_touch_dummy = 1; // this is used to make sure the compiler doesn't get too smart on us
@@ -260,14 +321,18 @@ namespace mongo {
260321
if ( rand() % mod == 0 )
261322
return false;
262323
} // end DEV test code
263-
324+
264325
if ( ! MemoryTrackingEnabled )
265326
return true;
266327

267328
const size_t page = (size_t)data >> 12;
268329
const size_t region = page >> 6;
269330
const size_t offset = page & 0x3f;
270331

332+
SimpleCache* sc = SimpleCache::get();
333+
if ( sc->inCache( page ) )
334+
return true;
335+
271336
if ( ps::rolling[ps::bigHash(region)].access( region , offset , false ) ) {
272337
#ifdef _DEBUG
273338
if ( blockSupported && ! ProcessInfo::blockInMemory( const_cast<char*>(data) ) ) {
@@ -289,10 +354,19 @@ namespace mongo {
289354

290355

291356
Record* Record::accessed() {
357+
if ( ! MemoryTrackingEnabled )
358+
return this;
359+
292360
const size_t page = (size_t)_data >> 12;
293361
const size_t region = page >> 6;
294362
const size_t offset = page & 0x3f;
295-
ps::rolling[ps::bigHash(region)].access( region , offset , true );
363+
364+
SimpleCache* sc = SimpleCache::get();
365+
if ( ! sc->inCache( page ) ) {
366+
ps::rolling[ps::bigHash(region)].access( region , offset , true );
367+
sc->add( page );
368+
}
369+
296370
return this;
297371
}
298372

0 commit comments

Comments
 (0)