libxr  1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
LibXR::Memory Class Reference

内存操作类 / Memory operation class More...

#include <libxr_mem.hpp>

Static Public Member Functions

static void FastCopy (void *dst, const void *src, size_t size)
 快速内存拷贝 / Fast memory copy
 
static void FastSet (void *dst, uint8_t value, size_t size)
 快速内存填充 / Fast memory fill
 
static int FastCmp (const void *a, const void *b, size_t size)
 快速内存比较 / Fast memory comparison
 

Detailed Description

内存操作类 / Memory operation class

Definition at line 10 of file libxr_mem.hpp.

Member Function Documentation

◆ FastCmp()

int LibXR::Memory::FastCmp ( const void * a,
const void * b,
size_t size )
static

快速内存比较 / Fast memory comparison

Parameters
a比较对象 A
b比较对象 B
size比较大小 / Comparison size
Returns
int 比较结果 / Comparison result

Definition at line 269 of file libxr_mem.cpp.

270{
271 const uint8_t* p = static_cast<const uint8_t*>(a);
272 const uint8_t* q = static_cast<const uint8_t*>(b);
273
274 if ((size == 0) || (p == q))
275 {
276 return 0;
277 }
278
279 auto byte_cmp = [](const uint8_t* x, const uint8_t* y, size_t n) -> int
280 {
281 for (size_t i = 0; i < n; ++i)
282 {
283 int diff = static_cast<int>(x[i]) - static_cast<int>(y[i]);
284 if (diff != 0)
285 {
286 return diff;
287 }
288 }
289 return 0;
290 };
291
292 uintptr_t p_off = reinterpret_cast<uintptr_t>(p) & (LIBXR_ALIGN_SIZE - 1);
293 uintptr_t q_off = reinterpret_cast<uintptr_t>(q) & (LIBXR_ALIGN_SIZE - 1);
294
295 // 若同相位:先补齐到 LIBXR_ALIGN_SIZE 对齐再做宽比较
296 if ((p_off == q_off) && (p_off != 0))
297 {
298 size_t head = LIBXR_ALIGN_SIZE - p_off;
299 if (head > size)
300 {
301 head = size;
302 }
303
304 while (head--)
305 {
306 int diff = static_cast<int>(*p++) - static_cast<int>(*q++);
307 if (diff != 0)
308 {
309 return diff;
310 }
311 --size;
312 }
313 }
314
315#if LIBXR_ALIGN_SIZE == 8
316 // 8-byte compare(仅在两者均 8 对齐时才安全/快)
317 if ((((reinterpret_cast<uintptr_t>(p) | reinterpret_cast<uintptr_t>(q)) & 7u) == 0u))
318 {
319 auto* pw = reinterpret_cast<const uint64_t*>(p);
320 auto* qw = reinterpret_cast<const uint64_t*>(q);
321
322 while (size >= 64)
323 {
324 if (pw[0] != qw[0])
325 {
326 return byte_cmp(reinterpret_cast<const uint8_t*>(pw + 0),
327 reinterpret_cast<const uint8_t*>(qw + 0), 8);
328 }
329 if (pw[1] != qw[1])
330 {
331 return byte_cmp(reinterpret_cast<const uint8_t*>(pw + 1),
332 reinterpret_cast<const uint8_t*>(qw + 1), 8);
333 }
334 if (pw[2] != qw[2])
335 {
336 return byte_cmp(reinterpret_cast<const uint8_t*>(pw + 2),
337 reinterpret_cast<const uint8_t*>(qw + 2), 8);
338 }
339 if (pw[3] != qw[3])
340 {
341 return byte_cmp(reinterpret_cast<const uint8_t*>(pw + 3),
342 reinterpret_cast<const uint8_t*>(qw + 3), 8);
343 }
344 if (pw[4] != qw[4])
345 {
346 return byte_cmp(reinterpret_cast<const uint8_t*>(pw + 4),
347 reinterpret_cast<const uint8_t*>(qw + 4), 8);
348 }
349 if (pw[5] != qw[5])
350 {
351 return byte_cmp(reinterpret_cast<const uint8_t*>(pw + 5),
352 reinterpret_cast<const uint8_t*>(qw + 5), 8);
353 }
354 if (pw[6] != qw[6])
355 {
356 return byte_cmp(reinterpret_cast<const uint8_t*>(pw + 6),
357 reinterpret_cast<const uint8_t*>(qw + 6), 8);
358 }
359 if (pw[7] != qw[7])
360 {
361 return byte_cmp(reinterpret_cast<const uint8_t*>(pw + 7),
362 reinterpret_cast<const uint8_t*>(qw + 7), 8);
363 }
364
365 pw += 8;
366 qw += 8;
367 size -= 64;
368 }
369
370 while (size >= 8)
371 {
372 if (*pw != *qw)
373 {
374 return byte_cmp(reinterpret_cast<const uint8_t*>(pw),
375 reinterpret_cast<const uint8_t*>(qw), 8);
376 }
377 ++pw;
378 ++qw;
379 size -= 8;
380 }
381
382 p = reinterpret_cast<const uint8_t*>(pw);
383 q = reinterpret_cast<const uint8_t*>(qw);
384 }
385#else
386 // 4-byte compare(两者均 4 对齐)
387 if ((((reinterpret_cast<uintptr_t>(p) | reinterpret_cast<uintptr_t>(q)) & 3u) == 0u))
388 {
389 auto* pw = reinterpret_cast<const uint32_t*>(p);
390 auto* qw = reinterpret_cast<const uint32_t*>(q);
391
392 while (size >= 32)
393 {
394 if (pw[0] != qw[0])
395 {
396 return byte_cmp(reinterpret_cast<const uint8_t*>(pw + 0),
397 reinterpret_cast<const uint8_t*>(qw + 0), 4);
398 }
399 if (pw[1] != qw[1])
400 {
401 return byte_cmp(reinterpret_cast<const uint8_t*>(pw + 1),
402 reinterpret_cast<const uint8_t*>(qw + 1), 4);
403 }
404 if (pw[2] != qw[2])
405 {
406 return byte_cmp(reinterpret_cast<const uint8_t*>(pw + 2),
407 reinterpret_cast<const uint8_t*>(qw + 2), 4);
408 }
409 if (pw[3] != qw[3])
410 {
411 return byte_cmp(reinterpret_cast<const uint8_t*>(pw + 3),
412 reinterpret_cast<const uint8_t*>(qw + 3), 4);
413 }
414 if (pw[4] != qw[4])
415 {
416 return byte_cmp(reinterpret_cast<const uint8_t*>(pw + 4),
417 reinterpret_cast<const uint8_t*>(qw + 4), 4);
418 }
419 if (pw[5] != qw[5])
420 {
421 return byte_cmp(reinterpret_cast<const uint8_t*>(pw + 5),
422 reinterpret_cast<const uint8_t*>(qw + 5), 4);
423 }
424 if (pw[6] != qw[6])
425 {
426 return byte_cmp(reinterpret_cast<const uint8_t*>(pw + 6),
427 reinterpret_cast<const uint8_t*>(qw + 6), 4);
428 }
429 if (pw[7] != qw[7])
430 {
431 return byte_cmp(reinterpret_cast<const uint8_t*>(pw + 7),
432 reinterpret_cast<const uint8_t*>(qw + 7), 4);
433 }
434
435 pw += 8;
436 qw += 8;
437 size -= 32;
438 }
439
440 while (size >= 4)
441 {
442 if (*pw != *qw)
443 {
444 return byte_cmp(reinterpret_cast<const uint8_t*>(pw),
445 reinterpret_cast<const uint8_t*>(qw), 4);
446 }
447 ++pw;
448 ++qw;
449 size -= 4;
450 }
451
452 p = reinterpret_cast<const uint8_t*>(pw);
453 q = reinterpret_cast<const uint8_t*>(qw);
454 }
455#endif
456
457 // tail byte compare(包括:未满足宽比较对齐条件的情况)
458 while (size--)
459 {
460 int diff = static_cast<int>(*p++) - static_cast<int>(*q++);
461 if (diff != 0)
462 {
463 return diff;
464 }
465 }
466
467 return 0;
468}

◆ FastCopy()

void LibXR::Memory::FastCopy ( void * dst,
const void * src,
size_t size )
static

快速内存拷贝 / Fast memory copy

Parameters
dst目标地址 / Destination address
src源地址 / Source address
size拷贝大小 / Copy size

If source and destination have the same alignment offset, we can perform fast aligned copying after handling the leading bytes.

Handle unaligned head bytes before reaching alignment.

Burst copy 4 bytes per cycle (32-bit), using 8x unrolled loop.

If alignments are different, try to maximize word copy size based on address difference.

Copy any remaining bytes (tail).

Definition at line 3 of file libxr_mem.cpp.

4{
5 uint8_t* d = static_cast<uint8_t*>(dst);
6 const uint8_t* s = static_cast<const uint8_t*>(src);
7
8 uintptr_t d_offset = reinterpret_cast<uintptr_t>(d) & (LIBXR_ALIGN_SIZE - 1);
9 uintptr_t s_offset = reinterpret_cast<uintptr_t>(s) & (LIBXR_ALIGN_SIZE - 1);
10
15 if (d_offset == s_offset)
16 {
18 if (d_offset)
19 {
20 size_t head = LIBXR_ALIGN_SIZE - d_offset;
21 if (head > size)
22 {
23 head = size;
24 }
25 while (head--)
26 {
27 *d++ = *s++;
28 --size;
29 }
30 }
31
32#if LIBXR_ALIGN_SIZE == 8
34 auto* dw = reinterpret_cast<uint64_t*>(d);
35 auto* sw = reinterpret_cast<const uint64_t*>(s);
36
37 while (size >= 64)
38 {
39 dw[0] = sw[0];
40 dw[1] = sw[1];
41 dw[2] = sw[2];
42 dw[3] = sw[3];
43 dw[4] = sw[4];
44 dw[5] = sw[5];
45 dw[6] = sw[6];
46 dw[7] = sw[7];
47 dw += 8;
48 sw += 8;
49 size -= 64;
50 }
51 while (size >= 8)
52 {
53 *dw++ = *sw++;
54 size -= 8;
55 }
56
57 d = reinterpret_cast<uint8_t*>(dw);
58 s = reinterpret_cast<const uint8_t*>(sw);
59#else
61 auto* dw = reinterpret_cast<uint32_t*>(d);
62 auto* sw = reinterpret_cast<const uint32_t*>(s);
63
64 while (size >= 32)
65 {
66 dw[0] = sw[0];
67 dw[1] = sw[1];
68 dw[2] = sw[2];
69 dw[3] = sw[3];
70 dw[4] = sw[4];
71 dw[5] = sw[5];
72 dw[6] = sw[6];
73 dw[7] = sw[7];
74 dw += 8;
75 sw += 8;
76 size -= 32;
77 }
78 while (size >= 4)
79 {
80 *dw++ = *sw++;
81 size -= 4;
82 }
83
84 d = reinterpret_cast<uint8_t*>(dw);
85 s = reinterpret_cast<const uint8_t*>(sw);
86#endif
87 }
92 else
93 {
94 uintptr_t addr_diff = reinterpret_cast<uintptr_t>(s) - reinterpret_cast<uintptr_t>(d);
95
96#if LIBXR_ALIGN_SIZE == 8
98 if ((addr_diff & 3) == 0 && size > 0)
99 {
100 while ((reinterpret_cast<uintptr_t>(d) & 3) && size)
101 {
102 *d++ = *s++;
103 --size;
104 }
105 auto* d32 = reinterpret_cast<uint32_t*>(d);
106 auto* s32 = reinterpret_cast<const uint32_t*>(s);
107
108 while (size >= 32)
109 {
110 d32[0] = s32[0];
111 d32[1] = s32[1];
112 d32[2] = s32[2];
113 d32[3] = s32[3];
114 d32[4] = s32[4];
115 d32[5] = s32[5];
116 d32[6] = s32[6];
117 d32[7] = s32[7];
118 d32 += 8;
119 s32 += 8;
120 size -= 32;
121 }
122 while (size >= 4)
123 {
124 *d32++ = *s32++;
125 size -= 4;
126 }
127
128 d = reinterpret_cast<uint8_t*>(d32);
129 s = reinterpret_cast<const uint8_t*>(s32);
130 }
132 else
133#endif
134 if ((addr_diff & 1) == 0 && size > 0)
135 {
136 if (reinterpret_cast<uintptr_t>(d) & 1)
137 {
138 *d++ = *s++;
139 --size;
140 }
141 auto* d16 = reinterpret_cast<uint16_t*>(d);
142 auto* s16 = reinterpret_cast<const uint16_t*>(s);
143
144 while (size >= 16)
145 {
146 d16[0] = s16[0];
147 d16[1] = s16[1];
148 d16[2] = s16[2];
149 d16[3] = s16[3];
150 d16[4] = s16[4];
151 d16[5] = s16[5];
152 d16[6] = s16[6];
153 d16[7] = s16[7];
154 d16 += 8;
155 s16 += 8;
156 size -= 16;
157 }
158 while (size >= 2)
159 {
160 *d16++ = *s16++;
161 size -= 2;
162 }
163
164 d = reinterpret_cast<uint8_t*>(d16);
165 s = reinterpret_cast<const uint8_t*>(s16);
166 }
167 // Otherwise, fallback to byte-wise copying below.
168 }
169
171 while (size--)
172 {
173 *d++ = *s++;
174 }
175}

◆ FastSet()

void LibXR::Memory::FastSet ( void * dst,
uint8_t value,
size_t size )
static

快速内存填充 / Fast memory fill

Parameters
dst目标地址 / Destination address
value填充值 / Fill value
size填充大小 / Fill size

Definition at line 177 of file libxr_mem.cpp.

178{
179 if (size == 0)
180 {
181 return;
182 }
183
184 uint8_t* d = static_cast<uint8_t*>(dst);
185
186 uintptr_t d_offset = reinterpret_cast<uintptr_t>(d) & (LIBXR_ALIGN_SIZE - 1);
187
188 // 先处理头部到对齐
189 if (d_offset)
190 {
191 size_t head = LIBXR_ALIGN_SIZE - d_offset;
192 if (head > size)
193 {
194 head = size;
195 }
196 while (head--)
197 {
198 *d++ = value;
199 --size;
200 }
201 }
202
203#if LIBXR_ALIGN_SIZE == 8
204 // 8-byte pattern
205 uint64_t pat = value;
206 pat |= pat << 8;
207 pat |= pat << 16;
208 pat |= pat << 32;
209
210 auto* dw = reinterpret_cast<uint64_t*>(d);
211
212 while (size >= 64)
213 {
214 dw[0] = pat;
215 dw[1] = pat;
216 dw[2] = pat;
217 dw[3] = pat;
218 dw[4] = pat;
219 dw[5] = pat;
220 dw[6] = pat;
221 dw[7] = pat;
222 dw += 8;
223 size -= 64;
224 }
225 while (size >= 8)
226 {
227 *dw++ = pat;
228 size -= 8;
229 }
230
231 d = reinterpret_cast<uint8_t*>(dw);
232#else
233 // 4-byte pattern
234 uint32_t pat = value;
235 pat |= pat << 8;
236 pat |= pat << 16;
237
238 auto* dw = reinterpret_cast<uint32_t*>(d);
239
240 while (size >= 32)
241 {
242 dw[0] = pat;
243 dw[1] = pat;
244 dw[2] = pat;
245 dw[3] = pat;
246 dw[4] = pat;
247 dw[5] = pat;
248 dw[6] = pat;
249 dw[7] = pat;
250 dw += 8;
251 size -= 32;
252 }
253 while (size >= 4)
254 {
255 *dw++ = pat;
256 size -= 4;
257 }
258
259 d = reinterpret_cast<uint8_t*>(dw);
260#endif
261
262 // 尾巴
263 while (size--)
264 {
265 *d++ = value;
266 }
267}

The documentation for this class was generated from the following files: