fastmem.h
Go to the documentation of this file.
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2014 Google Inc. All rights reserved.
3 // https://developers.google.com/protocol-buffers/
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 // * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 // * Redistributions in binary form must reproduce the above
12 // copyright notice, this list of conditions and the following disclaimer
13 // in the documentation and/or other materials provided with the
14 // distribution.
15 // * Neither the name of Google Inc. nor the names of its
16 // contributors may be used to endorse or promote products derived from
17 // this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 
31 // Fast memory copying and comparison routines.
32 // strings::fastmemcmp_inlined() replaces memcmp()
33 // strings::memcpy_inlined() replaces memcpy()
34 // strings::memeq(a, b, n) replaces memcmp(a, b, n) == 0
35 //
36 // strings::*_inlined() routines are inline versions of the
37 // routines exported by this module. Sometimes using the inlined
38 // versions is faster. Measure before using the inlined versions.
39 //
40 // Performance measurement:
41 // strings::fastmemcmp_inlined
42 // Analysis: memcmp, fastmemcmp_inlined, fastmemcmp
43 // 2012-01-30
44 
45 #ifndef GOOGLE_PROTOBUF_STUBS_FASTMEM_H_
46 #define GOOGLE_PROTOBUF_STUBS_FASTMEM_H_
47 
48 #include <stddef.h>
49 #include <stdio.h>
50 #include <string.h>
51 
52 #include <google/protobuf/stubs/common.h>
53 
54 #include <google/protobuf/port_def.inc>
55 
56 namespace google {
57 namespace protobuf {
58 namespace internal {
59 
60 // Return true if the n bytes at a equal the n bytes at b.
61 // The regions are allowed to overlap.
62 //
63 // The performance is similar to the performance memcmp(), but faster for
64 // moderately-sized inputs, or inputs that share a common prefix and differ
65 // somewhere in their last 8 bytes. Further optimizations can be added later
66 // if it makes sense to do so.:w
67 inline bool memeq(const char* a, const char* b, size_t n) {
68  size_t n_rounded_down = n & ~static_cast<size_t>(7);
69  if (PROTOBUF_PREDICT_FALSE(n_rounded_down == 0)) { // n <= 7
70  return memcmp(a, b, n) == 0;
71  }
72  // n >= 8
75  if ((u | v) != 0) { // The first or last 8 bytes differ.
76  return false;
77  }
78  a += 8;
79  b += 8;
80  n = n_rounded_down - 8;
81  if (n > 128) {
82  // As of 2012, memcmp on x86-64 uses a big unrolled loop with SSE2
83  // instructions, and while we could try to do something faster, it
84  // doesn't seem worth pursuing.
85  return memcmp(a, b, n) == 0;
86  }
87  for (; n >= 16; n -= 16) {
90  if ((x | y) != 0) {
91  return false;
92  }
93  a += 16;
94  b += 16;
95  }
96  // n must be 0 or 8 now because it was a multiple of 8 at the top of the loop.
98 }
99 
100 inline int fastmemcmp_inlined(const char *a, const char *b, size_t n) {
101  if (n >= 64) {
102  return memcmp(a, b, n);
103  }
104  const char* a_limit = a + n;
105  while (a + sizeof(uint64) <= a_limit &&
107  a += sizeof(uint64);
108  b += sizeof(uint64);
109  }
110  if (a + sizeof(uint32) <= a_limit &&
112  a += sizeof(uint32);
113  b += sizeof(uint32);
114  }
115  while (a < a_limit) {
116  int d =
117  static_cast<int>(static_cast<uint32>(*a++) - static_cast<uint32>(*b++));
118  if (d) return d;
119  }
120  return 0;
121 }
122 
123 // The standard memcpy operation is slow for variable small sizes.
124 // This implementation inlines the optimal realization for sizes 1 to 16.
125 // To avoid code bloat don't use it in case of not performance-critical spots,
126 // nor when you don't expect very frequent values of size <= 16.
127 inline void memcpy_inlined(char *dst, const char *src, size_t size) {
128  // Compiler inlines code with minimal amount of data movement when third
129  // parameter of memcpy is a constant.
130  switch (size) {
131  case 1: memcpy(dst, src, 1); break;
132  case 2: memcpy(dst, src, 2); break;
133  case 3: memcpy(dst, src, 3); break;
134  case 4: memcpy(dst, src, 4); break;
135  case 5: memcpy(dst, src, 5); break;
136  case 6: memcpy(dst, src, 6); break;
137  case 7: memcpy(dst, src, 7); break;
138  case 8: memcpy(dst, src, 8); break;
139  case 9: memcpy(dst, src, 9); break;
140  case 10: memcpy(dst, src, 10); break;
141  case 11: memcpy(dst, src, 11); break;
142  case 12: memcpy(dst, src, 12); break;
143  case 13: memcpy(dst, src, 13); break;
144  case 14: memcpy(dst, src, 14); break;
145  case 15: memcpy(dst, src, 15); break;
146  case 16: memcpy(dst, src, 16); break;
147  default: memcpy(dst, src, size); break;
148  }
149 }
150 
151 } // namespace internal
152 } // namespace protobuf
153 } // namespace google
154 
155 #include <google/protobuf/port_undef.inc>
156 
157 #endif // GOOGLE_PROTOBUF_STUBS_FASTMEM_H_
dst
static const char dst[]
Definition: test-fs-copyfile.c:37
google::protobuf.internal::fastmemcmp_inlined
int fastmemcmp_inlined(const char *a, const char *b, size_t n)
Definition: fastmem.h:100
y
const double y
Definition: bloaty/third_party/googletest/googlemock/test/gmock-matchers_test.cc:3611
string.h
google::protobuf::uint32
uint32_t uint32
Definition: third_party/bloaty/third_party/protobuf/src/google/protobuf/stubs/port.h:155
u
OPENSSL_EXPORT pem_password_cb void * u
Definition: pem.h:351
google::protobuf
Definition: bloaty/third_party/protobuf/benchmarks/util/data_proto2_to_proto3_util.h:12
a
int a
Definition: abseil-cpp/absl/container/internal/hash_policy_traits_test.cc:88
memcpy
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
setup.v
v
Definition: third_party/bloaty/third_party/capstone/bindings/python/setup.py:42
google::protobuf::uint64
uint64_t uint64
Definition: third_party/bloaty/third_party/protobuf/src/google/protobuf/stubs/port.h:156
x
int x
Definition: bloaty/third_party/googletest/googlemock/test/gmock-matchers_test.cc:3610
b
uint64_t b
Definition: abseil-cpp/absl/container/internal/layout_test.cc:53
n
int n
Definition: abseil-cpp/absl/container/btree_test.cc:1080
google::protobuf::GOOGLE_UNALIGNED_LOAD32
uint32 GOOGLE_UNALIGNED_LOAD32(const void *p)
Definition: third_party/bloaty/third_party/protobuf/src/google/protobuf/stubs/port.h:223
google::protobuf.internal::memeq
bool memeq(const char *a, const char *b, size_t n)
Definition: fastmem.h:67
google::protobuf::GOOGLE_UNALIGNED_LOAD64
uint64 GOOGLE_UNALIGNED_LOAD64(const void *p)
Definition: third_party/bloaty/third_party/protobuf/src/google/protobuf/stubs/port.h:229
google::protobuf.internal::memcpy_inlined
void memcpy_inlined(char *dst, const char *src, size_t size)
Definition: fastmem.h:127
internal
Definition: benchmark/test/output_test_helper.cc:20
size
voidpf void uLong size
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:136
google
Definition: bloaty/third_party/protobuf/benchmarks/util/data_proto2_to_proto3_util.h:11


grpc
Author(s):
autogenerated on Thu Mar 13 2025 02:59:19