gpt4 book ai didi

c - 为什么 FreeBSD 的 memchr 实现会在其条件下增加其指针?

转载 作者:太空狗 更新时间:2023-10-29 17:23:27 25 4
gpt4 key购买 nike

FreeBSD's generic implementation of memchr做:

void *
memchr(const void *s, int c, size_t n)
{
if (n != 0) {
const unsigned char *p = s;

do {
if (*p++ == (unsigned char)c)
return ((void *)(p - 1));
} while (--n != 0);
}
return (NULL);
}

这对我来说似乎不必要地复杂;最初的 n != 0 检查 do-while 只是为了避免 p 声明似乎完全没有意义。但是,我特别感兴趣的是为什么循环体会这样:

if (*p++ == (unsigned char)c)
return ((void *)(p - 1));

而不是更直接的:

if (*p == (unsigned char)c)
return ((void *) p);
++p;

使用条件内联后增量是否对某些编译器/平台有一些优化好处?

最佳答案

首先:这纯粹是猜测。我没有编写此代码,也无法验证我的猜测。

这两个版本的代码之间有一个非常重要的语义差异:

// Version A
if (*p++ == (unsigned char)c)
return ((void *)(p - 1));

// Version B
if (*p == (unsigned char)c)
return ((void *) p);
++p;

在版本 A 中,增量排在 if 的代码块之前,而在版本 B 中,它排在该 block 之后。

因此在版本 A 中,增量代码将被放置在可能从 if 生成的分支指令之前。至少我们可以 IMO 假设从 C 代码到编写代码时(1988 年?)编译器的汇编的这种相对直接的翻译。

Does inlining the post-increment with the condition have some optimization benefit for some compiler/platform?

在分支之前增加增量允许对分支指令具有 delay slot 的架构进行相对简单的优化: 你可以将增量移到那个延迟槽而不是在那里有一个 NOP。

因此,版本 A 每次循环迭代比版本 B 需要一条指令,代价是函数返回时只减少一次。这是一个(微)优化。

关于c - 为什么 FreeBSD 的 memchr 实现会在其条件下增加其指针?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42498719/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com