From: Piotr Dałek Date: Thu, 16 Jul 2015 09:19:37 +0000 (+0200) Subject: buffer.cc: short-circuit copy_in for small lengths X-Git-Tag: v9.1.0~333^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=311ef972cc1f794969459302b08e3de403ce7e06;p=ceph.git buffer.cc: short-circuit copy_in for small lengths For small lengths (below 64 bytes) use shorter code paths, this increases performance of function by up to 40%. Signed-off-by: Piotr Dałek --- diff --git a/src/common/buffer.cc b/src/common/buffer.cc index 7e34a03c29ce..5eccdfe05498 100644 --- a/src/common/buffer.cc +++ b/src/common/buffer.cc @@ -946,9 +946,49 @@ static simple_spinlock_t buffer_debug_lock = SIMPLE_SPINLOCK_INITIALIZER; assert(_raw); assert(o <= _len); assert(o+l <= _len); + char* dest = _raw->data + _off + o; if (crc_reset) _raw->invalidate_crc(); - memcpy(c_str()+o, src, l); + if (l < 64) { + switch (l) { + case 1: + *((uint8_t*)(dest)) = *((uint8_t*)(src)); + return; + case 2: + *((uint16_t*)(dest)) = *((uint16_t*)(src)); + return; + case 3: + *((uint16_t*)(dest)) = *((uint16_t*)(src)); + *((uint8_t*)(dest+2)) = *((uint8_t*)(src+2)); + return; + case 4: + *((uint32_t*)(dest)) = *((uint32_t*)(src)); + return; + case 8: + *((uint64_t*)(dest)) = *((uint64_t*)(src)); + return; + default: + int cursor = 0; + while (l >= sizeof(uint64_t)) { + *((uint64_t*)(dest + cursor)) = *((uint64_t*)(src + cursor)); + cursor += sizeof(uint64_t); + l -= sizeof(uint64_t); + } + while (l >= sizeof(uint32_t)) { + *((uint32_t*)(dest + cursor)) = *((uint32_t*)(src + cursor)); + cursor += sizeof(uint32_t); + l -= sizeof(uint32_t); + } + while (l > 0) { + *(dest + cursor) = *(src + cursor); + cursor++; + l--; + } + return; + } + } else { + memcpy(dest, src, l); + } } void buffer::ptr::zero(bool crc_reset)