Prefetch keys even in pure RAM scenarios

Former-commit-id: d7219de186d60a5a437c1828ac97117eaad34819
This commit is contained in:
John Sully 2021-03-26 23:48:24 +00:00
parent 1da03185e6
commit 01fb2a99bd
2 changed files with 26 additions and 3 deletions

View File

@ -35,6 +35,11 @@
#include <signal.h>
#include <ctype.h>
// Needed for prefetch
#if defined(__x86_64__) || defined(__i386__)
#include <xmmintrin.h>
#endif
/* Database backup. */
struct dbBackup {
const redisDbPersistentDataSnapshot **dbarray;
@ -3002,8 +3007,26 @@ int dbnumFromDb(redisDb *db)
void redisDbPersistentData::prefetchKeysAsync(client *c, parsed_command &command)
{
if (m_spstorage == nullptr)
if (m_spstorage == nullptr) {
#if defined(__x86_64__) || defined(__i386__)
// We do a quick 'n dirty check for set & get. Anything else is too slow.
// Should the user do something weird like remap them then the worst that will
// happen is we don't prefetch or we prefetch wrong data. A mild perf hit, but
// not dangerous
const char *cmd = szFromObj(command.argv[0]);
if (!strcasecmp(cmd, "set") || !strcasecmp(cmd, "get")) {
auto h = dictSdsHash(szFromObj(command.argv[1]));
for (int iht = 0; iht < 2; ++iht) {
auto hT = h & c->db->m_pdict->ht[iht].sizemask;
if (c->db->m_pdict->ht[iht].table != nullptr)
_mm_prefetch(c->db->m_pdict->ht[iht].table[hT], _MM_HINT_T1);
if (!dictIsRehashing(c->db->m_pdict))
break;
}
}
#endif
return;
}
AeLocker lock;

View File

@ -2358,8 +2358,8 @@ void parseClientCommandBuffer(client *c) {
serverAssert(c->vecqueuedcmd.back().reploff >= 0);
}
/* Prefetch if we have a storage provider and we're not in the global lock */
if (cqueries < c->vecqueuedcmd.size() && g_pserver->m_pstorageFactory != nullptr && !GlobalLocksAcquired()) {
/* Prefetch outside the lock for better perf */
if (cqueries < c->vecqueuedcmd.size() && !GlobalLocksAcquired()) {
auto &query = c->vecqueuedcmd.back();
if (query.argc > 0 && query.argc == query.argcMax) {
c->db->prefetchKeysAsync(c, query);