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 11 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 310 of file libxr_mem.cpp.

311{
312 const uint8_t* p = static_cast<const uint8_t*>(a);
313 const uint8_t* q = static_cast<const uint8_t*>(b);
314 const uint8_t* mismatch_p = nullptr;
315 const uint8_t* mismatch_q = nullptr;
316 size_t mismatch_size = 0;
317
318 if ((size == 0) || (p == q))
319 {
320 return 0;
321 }
322
323 uintptr_t p_off = reinterpret_cast<uintptr_t>(p) & (LibXR::ALIGN_SIZE - 1);
324 uintptr_t q_off = reinterpret_cast<uintptr_t>(q) & (LibXR::ALIGN_SIZE - 1);
325
326 // 若同相位:先补齐到 LibXR::ALIGN_SIZE 对齐再做宽比较
327 if ((p_off == q_off) && (p_off != 0))
328 {
329 size_t head = LibXR::ALIGN_SIZE - p_off;
330 if (head > size)
331 {
332 head = size;
333 }
334
335 while (head--)
336 {
337 int diff = static_cast<int>(*p++) - static_cast<int>(*q++);
338 if (diff != 0)
339 {
340 return diff;
341 }
342 --size;
343 }
344 }
345
346 if constexpr (LibXR::ALIGN_SIZE == 8)
347 {
348 // 8-byte compare(仅在两者均 8 对齐时才安全/快)
349 if ((((reinterpret_cast<uintptr_t>(p) | reinterpret_cast<uintptr_t>(q)) & 7u) == 0u))
350 {
351 auto* pw = reinterpret_cast<const uint64_t*>(p);
352 auto* qw = reinterpret_cast<const uint64_t*>(q);
353
354 while (size >= 64)
355 {
356 if (pw[0] != qw[0])
357 {
358 mismatch_p = reinterpret_cast<const uint8_t*>(pw + 0);
359 mismatch_q = reinterpret_cast<const uint8_t*>(qw + 0);
360 mismatch_size = 8;
361 goto compare_fixed_bytes;
362 }
363 if (pw[1] != qw[1])
364 {
365 mismatch_p = reinterpret_cast<const uint8_t*>(pw + 1);
366 mismatch_q = reinterpret_cast<const uint8_t*>(qw + 1);
367 mismatch_size = 8;
368 goto compare_fixed_bytes;
369 }
370 if (pw[2] != qw[2])
371 {
372 mismatch_p = reinterpret_cast<const uint8_t*>(pw + 2);
373 mismatch_q = reinterpret_cast<const uint8_t*>(qw + 2);
374 mismatch_size = 8;
375 goto compare_fixed_bytes;
376 }
377 if (pw[3] != qw[3])
378 {
379 mismatch_p = reinterpret_cast<const uint8_t*>(pw + 3);
380 mismatch_q = reinterpret_cast<const uint8_t*>(qw + 3);
381 mismatch_size = 8;
382 goto compare_fixed_bytes;
383 }
384 if (pw[4] != qw[4])
385 {
386 mismatch_p = reinterpret_cast<const uint8_t*>(pw + 4);
387 mismatch_q = reinterpret_cast<const uint8_t*>(qw + 4);
388 mismatch_size = 8;
389 goto compare_fixed_bytes;
390 }
391 if (pw[5] != qw[5])
392 {
393 mismatch_p = reinterpret_cast<const uint8_t*>(pw + 5);
394 mismatch_q = reinterpret_cast<const uint8_t*>(qw + 5);
395 mismatch_size = 8;
396 goto compare_fixed_bytes;
397 }
398 if (pw[6] != qw[6])
399 {
400 mismatch_p = reinterpret_cast<const uint8_t*>(pw + 6);
401 mismatch_q = reinterpret_cast<const uint8_t*>(qw + 6);
402 mismatch_size = 8;
403 goto compare_fixed_bytes;
404 }
405 if (pw[7] != qw[7])
406 {
407 mismatch_p = reinterpret_cast<const uint8_t*>(pw + 7);
408 mismatch_q = reinterpret_cast<const uint8_t*>(qw + 7);
409 mismatch_size = 8;
410 goto compare_fixed_bytes;
411 }
412
413 pw += 8;
414 qw += 8;
415 size -= 64;
416 }
417
418 while (size >= 8)
419 {
420 if (*pw != *qw)
421 {
422 mismatch_p = reinterpret_cast<const uint8_t*>(pw);
423 mismatch_q = reinterpret_cast<const uint8_t*>(qw);
424 mismatch_size = 8;
425 goto compare_fixed_bytes;
426 }
427 ++pw;
428 ++qw;
429 size -= 8;
430 }
431
432 p = reinterpret_cast<const uint8_t*>(pw);
433 q = reinterpret_cast<const uint8_t*>(qw);
434 }
435 }
436 else
437 {
438 // 4-byte compare(两者均 4 对齐)
439 if ((((reinterpret_cast<uintptr_t>(p) | reinterpret_cast<uintptr_t>(q)) & 3u) == 0u))
440 {
441 auto* pw = reinterpret_cast<const uint32_t*>(p);
442 auto* qw = reinterpret_cast<const uint32_t*>(q);
443
444 while (size >= 32)
445 {
446 if (pw[0] != qw[0])
447 {
448 mismatch_p = reinterpret_cast<const uint8_t*>(pw + 0);
449 mismatch_q = reinterpret_cast<const uint8_t*>(qw + 0);
450 mismatch_size = 4;
451 goto compare_fixed_bytes;
452 }
453 if (pw[1] != qw[1])
454 {
455 mismatch_p = reinterpret_cast<const uint8_t*>(pw + 1);
456 mismatch_q = reinterpret_cast<const uint8_t*>(qw + 1);
457 mismatch_size = 4;
458 goto compare_fixed_bytes;
459 }
460 if (pw[2] != qw[2])
461 {
462 mismatch_p = reinterpret_cast<const uint8_t*>(pw + 2);
463 mismatch_q = reinterpret_cast<const uint8_t*>(qw + 2);
464 mismatch_size = 4;
465 goto compare_fixed_bytes;
466 }
467 if (pw[3] != qw[3])
468 {
469 mismatch_p = reinterpret_cast<const uint8_t*>(pw + 3);
470 mismatch_q = reinterpret_cast<const uint8_t*>(qw + 3);
471 mismatch_size = 4;
472 goto compare_fixed_bytes;
473 }
474 if (pw[4] != qw[4])
475 {
476 mismatch_p = reinterpret_cast<const uint8_t*>(pw + 4);
477 mismatch_q = reinterpret_cast<const uint8_t*>(qw + 4);
478 mismatch_size = 4;
479 goto compare_fixed_bytes;
480 }
481 if (pw[5] != qw[5])
482 {
483 mismatch_p = reinterpret_cast<const uint8_t*>(pw + 5);
484 mismatch_q = reinterpret_cast<const uint8_t*>(qw + 5);
485 mismatch_size = 4;
486 goto compare_fixed_bytes;
487 }
488 if (pw[6] != qw[6])
489 {
490 mismatch_p = reinterpret_cast<const uint8_t*>(pw + 6);
491 mismatch_q = reinterpret_cast<const uint8_t*>(qw + 6);
492 mismatch_size = 4;
493 goto compare_fixed_bytes;
494 }
495 if (pw[7] != qw[7])
496 {
497 mismatch_p = reinterpret_cast<const uint8_t*>(pw + 7);
498 mismatch_q = reinterpret_cast<const uint8_t*>(qw + 7);
499 mismatch_size = 4;
500 goto compare_fixed_bytes;
501 }
502
503 pw += 8;
504 qw += 8;
505 size -= 32;
506 }
507
508 while (size >= 4)
509 {
510 if (*pw != *qw)
511 {
512 mismatch_p = reinterpret_cast<const uint8_t*>(pw);
513 mismatch_q = reinterpret_cast<const uint8_t*>(qw);
514 mismatch_size = 4;
515 goto compare_fixed_bytes;
516 }
517 ++pw;
518 ++qw;
519 size -= 4;
520 }
521
522 p = reinterpret_cast<const uint8_t*>(pw);
523 q = reinterpret_cast<const uint8_t*>(qw);
524 }
525 }
526
527compare_fixed_bytes:
528 if (mismatch_size == 8)
529 {
530 int diff = static_cast<int>(mismatch_p[0]) - static_cast<int>(mismatch_q[0]);
531 if (diff != 0)
532 {
533 return diff;
534 }
535 diff = static_cast<int>(mismatch_p[1]) - static_cast<int>(mismatch_q[1]);
536 if (diff != 0)
537 {
538 return diff;
539 }
540 diff = static_cast<int>(mismatch_p[2]) - static_cast<int>(mismatch_q[2]);
541 if (diff != 0)
542 {
543 return diff;
544 }
545 diff = static_cast<int>(mismatch_p[3]) - static_cast<int>(mismatch_q[3]);
546 if (diff != 0)
547 {
548 return diff;
549 }
550 diff = static_cast<int>(mismatch_p[4]) - static_cast<int>(mismatch_q[4]);
551 if (diff != 0)
552 {
553 return diff;
554 }
555 diff = static_cast<int>(mismatch_p[5]) - static_cast<int>(mismatch_q[5]);
556 if (diff != 0)
557 {
558 return diff;
559 }
560 diff = static_cast<int>(mismatch_p[6]) - static_cast<int>(mismatch_q[6]);
561 if (diff != 0)
562 {
563 return diff;
564 }
565 return static_cast<int>(mismatch_p[7]) - static_cast<int>(mismatch_q[7]);
566 }
567
568 if (mismatch_size == 4)
569 {
570 int diff = static_cast<int>(mismatch_p[0]) - static_cast<int>(mismatch_q[0]);
571 if (diff != 0)
572 {
573 return diff;
574 }
575 diff = static_cast<int>(mismatch_p[1]) - static_cast<int>(mismatch_q[1]);
576 if (diff != 0)
577 {
578 return diff;
579 }
580 diff = static_cast<int>(mismatch_p[2]) - static_cast<int>(mismatch_q[2]);
581 if (diff != 0)
582 {
583 return diff;
584 }
585 return static_cast<int>(mismatch_p[3]) - static_cast<int>(mismatch_q[3]);
586 }
587
588 // tail byte compare(包括:未满足宽比较对齐条件的情况)
589 while (size--)
590 {
591 int diff = static_cast<int>(*p++) - static_cast<int>(*q++);
592 if (diff != 0)
593 {
594 return diff;
595 }
596 }
597
598 return 0;
599}
constexpr size_t ALIGN_SIZE
平台自然对齐大小 / Native platform alignment size
Definition libxr_def.hpp:35

◆ 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 8 bytes per cycle (64-bit), using 8x unrolled loop.

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.

If address difference is a multiple of 4, use 4-byte copying.

If address difference is even, use 2-byte copying.

Copy any remaining bytes (tail).

Definition at line 5 of file libxr_mem.cpp.

6{
7 uint8_t* d = static_cast<uint8_t*>(dst);
8 const uint8_t* s = static_cast<const uint8_t*>(src);
9
10 uintptr_t d_offset = reinterpret_cast<uintptr_t>(d) & (LibXR::ALIGN_SIZE - 1);
11 uintptr_t s_offset = reinterpret_cast<uintptr_t>(s) & (LibXR::ALIGN_SIZE - 1);
12
17 if (d_offset == s_offset)
18 {
20 if (d_offset)
21 {
22 size_t head = LibXR::ALIGN_SIZE - d_offset;
23 if (head > size)
24 {
25 head = size;
26 }
27 while (head--)
28 {
29 *d++ = *s++;
30 --size;
31 }
32 }
33
34 if constexpr (LibXR::ALIGN_SIZE == 8)
35 {
37 auto* dw = reinterpret_cast<uint64_t*>(d);
38 auto* sw = reinterpret_cast<const uint64_t*>(s);
39
40 while (size >= 64)
41 {
42 dw[0] = sw[0];
43 dw[1] = sw[1];
44 dw[2] = sw[2];
45 dw[3] = sw[3];
46 dw[4] = sw[4];
47 dw[5] = sw[5];
48 dw[6] = sw[6];
49 dw[7] = sw[7];
50 dw += 8;
51 sw += 8;
52 size -= 64;
53 }
54 while (size >= 8)
55 {
56 *dw++ = *sw++;
57 size -= 8;
58 }
59
60 d = reinterpret_cast<uint8_t*>(dw);
61 s = reinterpret_cast<const uint8_t*>(sw);
62 }
63 else
64 {
66 auto* dw = reinterpret_cast<uint32_t*>(d);
67 auto* sw = reinterpret_cast<const uint32_t*>(s);
68
69 while (size >= 32)
70 {
71 dw[0] = sw[0];
72 dw[1] = sw[1];
73 dw[2] = sw[2];
74 dw[3] = sw[3];
75 dw[4] = sw[4];
76 dw[5] = sw[5];
77 dw[6] = sw[6];
78 dw[7] = sw[7];
79 dw += 8;
80 sw += 8;
81 size -= 32;
82 }
83 while (size >= 4)
84 {
85 *dw++ = *sw++;
86 size -= 4;
87 }
88
89 d = reinterpret_cast<uint8_t*>(dw);
90 s = reinterpret_cast<const uint8_t*>(sw);
91 }
92 }
97 else
98 {
99 uintptr_t addr_diff = reinterpret_cast<uintptr_t>(s) - reinterpret_cast<uintptr_t>(d);
100
101 if constexpr (LibXR::ALIGN_SIZE == 8)
102 {
104 if ((addr_diff & 3) == 0 && size > 0)
105 {
106 while ((reinterpret_cast<uintptr_t>(d) & 3) && size)
107 {
108 *d++ = *s++;
109 --size;
110 }
111 auto* d32 = reinterpret_cast<uint32_t*>(d);
112 auto* s32 = reinterpret_cast<const uint32_t*>(s);
113
114 while (size >= 32)
115 {
116 d32[0] = s32[0];
117 d32[1] = s32[1];
118 d32[2] = s32[2];
119 d32[3] = s32[3];
120 d32[4] = s32[4];
121 d32[5] = s32[5];
122 d32[6] = s32[6];
123 d32[7] = s32[7];
124 d32 += 8;
125 s32 += 8;
126 size -= 32;
127 }
128 while (size >= 4)
129 {
130 *d32++ = *s32++;
131 size -= 4;
132 }
133
134 d = reinterpret_cast<uint8_t*>(d32);
135 s = reinterpret_cast<const uint8_t*>(s32);
136 }
138 else if ((addr_diff & 1) == 0 && size > 0)
139 {
140 if (reinterpret_cast<uintptr_t>(d) & 1)
141 {
142 *d++ = *s++;
143 --size;
144 }
145 auto* d16 = reinterpret_cast<uint16_t*>(d);
146 auto* s16 = reinterpret_cast<const uint16_t*>(s);
147
148 while (size >= 16)
149 {
150 d16[0] = s16[0];
151 d16[1] = s16[1];
152 d16[2] = s16[2];
153 d16[3] = s16[3];
154 d16[4] = s16[4];
155 d16[5] = s16[5];
156 d16[6] = s16[6];
157 d16[7] = s16[7];
158 d16 += 8;
159 s16 += 8;
160 size -= 16;
161 }
162 while (size >= 2)
163 {
164 *d16++ = *s16++;
165 size -= 2;
166 }
167
168 d = reinterpret_cast<uint8_t*>(d16);
169 s = reinterpret_cast<const uint8_t*>(s16);
170 }
171 }
172 else if ((addr_diff & 1) == 0 && size > 0)
173 {
174 if (reinterpret_cast<uintptr_t>(d) & 1)
175 {
176 *d++ = *s++;
177 --size;
178 }
179 auto* d16 = reinterpret_cast<uint16_t*>(d);
180 auto* s16 = reinterpret_cast<const uint16_t*>(s);
181
182 while (size >= 16)
183 {
184 d16[0] = s16[0];
185 d16[1] = s16[1];
186 d16[2] = s16[2];
187 d16[3] = s16[3];
188 d16[4] = s16[4];
189 d16[5] = s16[5];
190 d16[6] = s16[6];
191 d16[7] = s16[7];
192 d16 += 8;
193 s16 += 8;
194 size -= 16;
195 }
196 while (size >= 2)
197 {
198 *d16++ = *s16++;
199 size -= 2;
200 }
201
202 d = reinterpret_cast<uint8_t*>(d16);
203 s = reinterpret_cast<const uint8_t*>(s16);
204 }
205 // Otherwise, fallback to byte-wise copying below.
206 }
207
209 while (size--)
210 {
211 *d++ = *s++;
212 }
213}

◆ 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 215 of file libxr_mem.cpp.

216{
217 if (size == 0)
218 {
219 return;
220 }
221
222 uint8_t* d = static_cast<uint8_t*>(dst);
223
224 uintptr_t d_offset = reinterpret_cast<uintptr_t>(d) & (LibXR::ALIGN_SIZE - 1);
225
226 // 先处理头部到对齐
227 if (d_offset)
228 {
229 size_t head = LibXR::ALIGN_SIZE - d_offset;
230 if (head > size)
231 {
232 head = size;
233 }
234 while (head--)
235 {
236 *d++ = value;
237 --size;
238 }
239 }
240
241 if constexpr (LibXR::ALIGN_SIZE == 8)
242 {
243 // 8-byte pattern
244 uint64_t pat = value;
245 pat |= pat << 8;
246 pat |= pat << 16;
247 pat |= pat << 32;
248
249 auto* dw = reinterpret_cast<uint64_t*>(d);
250
251 while (size >= 64)
252 {
253 dw[0] = pat;
254 dw[1] = pat;
255 dw[2] = pat;
256 dw[3] = pat;
257 dw[4] = pat;
258 dw[5] = pat;
259 dw[6] = pat;
260 dw[7] = pat;
261 dw += 8;
262 size -= 64;
263 }
264 while (size >= 8)
265 {
266 *dw++ = pat;
267 size -= 8;
268 }
269
270 d = reinterpret_cast<uint8_t*>(dw);
271 }
272 else
273 {
274 // 4-byte pattern
275 uint32_t pat = value;
276 pat |= pat << 8;
277 pat |= pat << 16;
278
279 auto* dw = reinterpret_cast<uint32_t*>(d);
280
281 while (size >= 32)
282 {
283 dw[0] = pat;
284 dw[1] = pat;
285 dw[2] = pat;
286 dw[3] = pat;
287 dw[4] = pat;
288 dw[5] = pat;
289 dw[6] = pat;
290 dw[7] = pat;
291 dw += 8;
292 size -= 32;
293 }
294 while (size >= 4)
295 {
296 *dw++ = pat;
297 size -= 4;
298 }
299
300 d = reinterpret_cast<uint8_t*>(dw);
301 }
302
303 // 尾巴
304 while (size--)
305 {
306 *d++ = value;
307 }
308}

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