diff --git a/src/networking.c b/src/networking.c index 7c8d900c8..10f1b3c29 100644 --- a/src/networking.c +++ b/src/networking.c @@ -1090,6 +1090,8 @@ void addReplyBulk(client *c, robj *obj) { if (_prepareClientToWrite(c) != C_OK) return; if (sdsEncodedObject(obj)) { + /* Prefetch the memory for the `flags` and potential header */ + redis_prefetch_read((const sds)(obj->ptr) - 1); const size_t len = sdslen(obj->ptr); _addReplyLongLongBulk(c, len); _addReplyToBufferOrList(c,obj->ptr,len); diff --git a/src/sds.h b/src/sds.h index c4cbf6bf5..4d4e33b51 100644 --- a/src/sds.h +++ b/src/sds.h @@ -17,6 +17,7 @@ extern const char *SDS_NOINIT; #include #include #include +#include "config.h" typedef char *sds; @@ -61,6 +62,8 @@ struct __attribute__ ((__packed__)) sdshdr64 { #define SDS_HDR_VAR(T,s) struct sdshdr##T *sh = (void*)((s)-(sizeof(struct sdshdr##T))); #define SDS_HDR(T,s) ((struct sdshdr##T *)((s)-(sizeof(struct sdshdr##T)))) #define SDS_TYPE_5_LEN(f) ((f)>>SDS_TYPE_BITS) +/* Prefetch based on the SDS type, into all cache levels (L1, L2, etc.). */ +#define SDS_HDR_PREFETCH(T, s) redis_prefetch_read((const char *)((s) - sizeof(struct sdshdr##T))) static inline size_t sdslen(const sds s) { unsigned char flags = s[-1]; @@ -68,12 +71,16 @@ static inline size_t sdslen(const sds s) { case SDS_TYPE_5: return SDS_TYPE_5_LEN(flags); case SDS_TYPE_8: + // SDS_HDR_PREFETCH(8,s); return SDS_HDR(8,s)->len; case SDS_TYPE_16: + // SDS_HDR_PREFETCH(16,s); return SDS_HDR(16,s)->len; case SDS_TYPE_32: + // SDS_HDR_PREFETCH(32,s); return SDS_HDR(32,s)->len; case SDS_TYPE_64: + // SDS_HDR_PREFETCH(64,s); return SDS_HDR(64,s)->len; } return 0; diff --git a/src/t_string.c b/src/t_string.c index 18396b834..344845987 100644 --- a/src/t_string.c +++ b/src/t_string.c @@ -310,7 +310,6 @@ int getGenericCommand(client *c) { if (checkType(c,o,OBJ_STRING)) { return C_ERR; } - addReplyBulk(c,o); return C_OK; }