我正在从 glibc 读取“strlen”源代码,开发人员发现加快它的技巧是读取 n 个字节,其中 n 是一个长字的大小,而不是在每次迭代时读取 1 个字节。
我假设一个长字有 4 个字节。
棘手的部分是函数读取的每个 4 字节的“块”都可以包含一个空字节,因此在每次迭代时,函数必须检查块中是否有空字节。他们这样做
if (((longword - lomagic) & ~longword & himagic) != 0) { /* null byte found */ }
Run Code Online (Sandbox Code Playgroud)
哪里longword是数据块,himagic和lowmagic是神奇的值,定义为:
himagic = 0x80808080L;
lomagic = 0x01010101L;
Run Code Online (Sandbox Code Playgroud)
这是对这些值的评论
/* Bits 31, 24, 16, and 8 of this number are zero. Call these bits
the "holes." Note that there is a hole just to the left of
each byte, with an extra at …Run Code Online (Sandbox Code Playgroud) 我最近研究了一个用GCC 8编译的软件中的segfault。代码如下(这只是一个草图)
struct Point
{
int64_t x, y;
};
struct Edge
{
// some other fields
// ...
Point p; // <- at offset `0xC0`
Edge(const Point &p) p(p) {}
};
Edge *create_edge(const Point &p)
{
void *raw_memory = my_custom_allocator(sizeof(Edge));
return new (raw_memory) Edge(p);
}
Run Code Online (Sandbox Code Playgroud)
这里的关键点是my_custom_allocator()返回指向未对齐内存的指针。代码崩溃是因为为了将原始点复制p到Edge::p新对象的字段中,编译器在 [内联] 构造函数代码中使用了movdqu/movaps对
movdqu 0x0(%rbp), %xmm1 ; read the original object at `rbp`
...
movaps %xmm1, 0xc0(%rbx) ; store it into the new `Edge` object …Run Code Online (Sandbox Code Playgroud) 我正在 C11 中实现一个 shell,我想在执行系统调用以执行命令之前检查输入是否具有正确的语法。我要防范的可能输入之一是仅由空白字符组成的字符串。检查字符串是否仅包含空格、制表符或任何其他空格字符的有效方法是什么?
解决方案必须在 C11 中,并且最好使用标准库。使用readline()from从命令行读取的字符串readline.h,并保存在字符数组 ( char[]) 中。到目前为止,我想到的唯一解决方案是遍历数组,并char使用isspace(). 有没有更有效的方法?
所以我将这个主数组保存在一个时间数组中。然后,我使用'\ 0'来“删除”其内部的主数组。在这一点上,如果我打印主数组,它将只打印空白。但是,如果那样的话,我使用for喜欢主数组=时间数组。x = 0 x <4 x ++时,它确实从另一个数组复制了四件事,但同时也打印了我执行“ \ 0”之前的内容
香港专业教育学院尝试了一段时间的柜台,但也没有工作。香港专业教育学院以前使用\ 0,它的工作idk为什么现在不工作
for(int y = 0; y <= strlen(numeros); y++){
numeros[y] = '\0';
}
printf("%s\n", numeros);
for(int z = 0; z <= 4; z++){
numeros[z] = numerosTemp[z];
}
printf("%s\n", numeros);
Run Code Online (Sandbox Code Playgroud)
我的预期结果只是numerosTemp数组的前四个字母,但是它包含了我在\ 0之前曾经拥有的所有内容。但是在\ 0之后的printf中,它只会打印空白,所以我不明白为什么会这样
我有memchr我要使非分支的这段代码:
.globl memchr
memchr:
mov %rdx, %rcx
mov %sil, %al
cld
repne scasb
lea -1(%rdi), %rax
test %rcx, %rcx
cmove %rcx, %rax
ret
Run Code Online (Sandbox Code Playgroud)
我不确定是否cmove是分支指令。是吗?如果是这样,如何重新排列我的代码,使其不分支?
assembly x86-64 cpu-architecture micro-optimization branch-prediction
我听说
strlen()C 标准库中的字符串操作(例如)访问和操作字符串的字符,一次一个字符。以上是真的吗?
有哪些解决方案可以提高字符串操作的时间性能?
c ×4
c-strings ×2
arrays ×1
assembly ×1
c++ ×1
c11 ×1
gcc ×1
optimization ×1
performance ×1
string ×1
strlen ×1
whitespace ×1
x86 ×1
x86-64 ×1