gpt4 book ai didi

c++ - 如何保持无法访问的代码?

转载 作者:太空狗 更新时间:2023-10-29 19:41:12 35 4
gpt4 key购买 nike

我想编写一个函数,该函数可以根据用户设置执行或不执行一些可选代码。该函数是 cpu 密集型的,并且由于分支预测器不是那么好,所以其中包含 ifs 会很慢。

我的想法是在函数的内存中复制一份,并在我不想执行某些代码时用跳转替换 NOP。我的工作示例是这样的:

int Test()
{
int x = 2;
for (int i=0 ; i<10 ; i++)
{
x *= 2;

__asm {NOP}; // to skip it replace this
__asm {NOP}; // by JMP 2 (after the goto)
x *= 2; // Op to skip or not

x *= 2;
}
return x;
}

在我的测试主程序中,我将此函数复制到新分配的可执行内存中,并用 JMP 2 替换 NOP,以便不执行以下 x *= 2。 JMP 2 确实是“跳过接下来的 2 个字节”。

问题是每次编辑要跳过的代码并更改其大小时,我都必须更改 JMP 操作数。

解决此问题的替代方法是:

__asm {NOP}; // to skip it replace this
__asm {NOP}; // by JMP 2 (after the goto)
goto dont_do_it;
x *= 2; // Op to skip or not
dont_do_it:
x *= 2;

然后我想跳过或不跳过具有固定大小的 goto。不幸的是,在完全优化模式下,goto 和 x*=2 被删除,因为它们在编译时不可访问。

因此需要保留死代码。

我使用的是 VStudio 2008。

最佳答案

只需将分支移出循环,您最多可以将分支成本降低 10:

int Test()
{
int x = 2;
if (should_skip) {
for (int i=0 ; i<10 ; i++)
{
x *= 2;
x *= 2;
}
} else {
for (int i=0 ; i<10 ; i++)
{
x *= 2;
x *= 2;
x *= 2;
}
}

return x;
}

在这种情况下,以及其他类似的情况下,这也可能促使编译器更好地优化循环体,因为它会分别考虑这两种可能性,而不是尝试优化条件代码,而且它不会优化任何东西。

如果这导致太多重复代码难以维护,请使用通过引用获取 x 的模板:

    int x = 2;
if (should_skip) {
doLoop<true>(x);
} else {
doLoop<false>(x);
}

并检查编译器是否内联它。

显然这会稍微增加代码大小,这偶尔会成为一个问题。不过,无论您采用哪种方式,如果此更改没有产生可衡量的性能改进,那么我猜您的也不会。

关于c++ - 如何保持无法访问的代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2563398/

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