相关疑难解决方法(0)

如何确定一个字节中的一个字节是否为空

我正在从 glibc 读取“strlen”源代码,开发人员发现加快它的技巧是读取 n 个字节,其中 n 是一个长字的大小,而不是在每次迭代时读取 1 个字节。

我假设一个长字有 4 个字节。

棘手的部分是函数读取的每个 4 字节的“块”都可以包含一个空字节,因此在每次迭代时,函数必须检查块中是否有空字节。他们这样做

if (((longword - lomagic) & ~longword & himagic) != 0) { /* null byte found */ }
Run Code Online (Sandbox Code Playgroud)

哪里longword是数据块,himagiclowmagic是神奇的值,定义为:

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)

c magic-numbers strlen

3
推荐指数
1
解决办法
1986
查看次数

GCC 中的 `movaps` 与 `movups`:它是如何决定的?

我最近研究了一个用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()返回指向未对齐内存的指针。代码崩溃是因为为了将原始点复制pEdge::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)

c++ optimization x86 gcc memory-alignment

3
推荐指数
1
解决办法
1802
查看次数

检查字符串在 C 中是否只有空白字符

我正在 C11 中实现一个 shell,我想在执行系统调用以执行命令之前检查输入是否具有正确的语法。我要防范的可能输入之一是仅由空白字符组成的字符串。检查字符串是否仅包含空格、制表符或任何其他空格字符的有效方法是什么?

解决方案必须在 C11 中,并且最好使用标准库。使用readline()from从命令行读取的字符串readline.h,并保存在字符数组 ( char[]) 中。到目前为止,我想到的唯一解决方案是遍历数组,并char使用isspace(). 有没有更有效的方法?

c whitespace c11

2
推荐指数
1
解决办法
1622
查看次数

为什么我的阵列没有正确清空?

所以我将这个主数组保存在一个时间数组中。然后,我使用'\ 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中,它只会打印空白,所以我不明白为什么会这样

c arrays c-strings

1
推荐指数
1
解决办法
62
查看次数

CMOVcc是否被视为分支指令?

我有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

-1
推荐指数
1
解决办法
128
查看次数

字符串操作是否因为一次访问一个字符而效率低下?

我听说

  • strlen()C 标准库中的字符串操作(例如)访问和操作字符串的字符,一次一个字符。
  • 计算机一次访问内存中的一个单词。
  • 一次访问一个字符效率低下,字符串操作的时间成本很高。

以上是真的吗?

有哪些解决方案可以提高字符串操作的时间性能?

c string performance c-strings

-1
推荐指数
1
解决办法
90
查看次数