void my_memset(char *a, char c, unsigned n) {
/* glibc is excellent for small/medium fills and awkward tails. */
if (n < (1u << 20)) {
__builtin_memset(a, (unsigned char)c, n);
return;
}
/* Align non-temporal stores to a cache-line boundary. */
unsigned head = (unsigned)(-(unsigned long)a) & 63u;
if (head > n)
head = n;
unsigned long head_count = head;
__asm__ volatile ("rep stosb"
: "+D"(a), "+c"(head_count)
: "a"((unsigned char)c)
: "memory");
n -= head;
unsigned tail = n & 255u;
unsigned long bulk = n - tail;
if (bulk != 0) {
const unsigned long pattern =
0x0101010101010101UL * (unsigned char)c;
__asm__ volatile (
"vmovq %[pattern], %%xmm0\n\t"
"vpbroadcastq %%xmm0, %%ymm0\n\t"
".p2align 5\n\t"
"1:\n\t"
"vmovntdq %%ymm0, 0(%[dst])\n\t"
"vmovntdq %%ymm0, 32(%[dst])\n\t"
"vmovntdq %%ymm0, 64(%[dst])\n\t"
"vmovntdq %%ymm0, 96(%[dst])\n\t"
"vmovntdq %%ymm0, 128(%[dst])\n\t"
"vmovntdq %%ymm0, 160(%[dst])\n\t"
"vmovntdq %%ymm0, 192(%[dst])\n\t"
"vmovntdq %%ymm0, 224(%[dst])\n\t"
"add $256, %[dst]\n\t"
"sub $256, %[bulk]\n\t"
"jne 1b\n\t"
"sfence\n\t"
"vzeroupper"
: [dst] "+r"(a), [bulk] "+r"(bulk)
: [pattern] "r"(pattern)
: "xmm0", "memory", "cc");
}
unsigned long tail_count = tail;
__asm__ volatile ("rep stosb"
: "+D"(a), "+c"(tail_count)
: "a"((unsigned char)c)
: "memory");
}
| Compilation | N/A | N/A | Compile Error | Score: N/A | 显示更多 |