相关疑难解决方法(0)

还在继续吗?

在以下两个代码片段中,根据编译或运行的速度,实际上是否有任何不同?

for (int i = 0; i < 50; i++)
{
    if (i % 3 == 0)
        continue;

    printf("Yay");
}
Run Code Online (Sandbox Code Playgroud)

for (int i = 0; i < 50; i++)
{
    if (i % 3 != 0)
        printf("Yay");
}
Run Code Online (Sandbox Code Playgroud)

就个人而言,在存在多于print语句的情况下,我一直在使用第一种方法来减少包含代码的缩进量.想知道一段时间,所以发现它的时间我问它是否实际上有除了视觉效果.

回复Alf(我无法让代码在评论中工作......)

对我的用法更准确的是"handleObjectMovement"函数的行,其中包括

for each object
    if object position is static
        continue

    deal with velocity and jazz
Run Code Online (Sandbox Code Playgroud)

和....相比

for each object
    if object position is not static
        deal with velocity and jazz
Run Code Online (Sandbox Code Playgroud)

因此我没有使用回报.基本上"如果它与此迭代无关,请继续"

c++ continue compiler-optimization

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

是否有可能帮助分支预测?

您是否可以有意识地以特定方式编写代码,以便分支预测器将选择大多数情况下的选项.例如,错误检查资源是否已加载.如果可能的话,你如何利用这个优势?

c c++ java branch-prediction

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

循环中复制与去重相同条件代码的性能

假设我有这样的代码,称之为版本 1:

while (some_condition) {
    // .. work that may trigger rare_condition ...

    if (rare_condition) {
        // .. rare work here ..
        continue;
    }

    // .. work that may trigger rare_condition ...

    if (rare_condition) {
        // .. rare work here ..
        continue;
    }

    // .. more work
}
Run Code Online (Sandbox Code Playgroud)

假设这两种情况下的“稀有作品”是相同的。我们可以等效地编写版本 2:

while (some_condition) {
    // .. work that may trigger rare_condition ...

    if (rare_condition) {
        goto rare_work;
    }

    // .. work that may trigger rare_condition ...

    if (rare_condition) {
        goto rare_work; …
Run Code Online (Sandbox Code Playgroud)

c optimization performance assembly x86-64

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

在不使用条件编译的情况下加速C程序

我们正在研究一种模型检查工具,它可以执行几十亿次搜索程序.我们有不同的搜索例程,目前使用预处理器指令进行选择.这不仅非常不方便,因为我们每次做出不同的选择时都需要重新编译,但也使代码难以阅读.现在是开始新版本的时候了,我们正在评估是否可以避免条件编译.

这是一个非常人为的例子,显示了效果:

/* program_define */

#include <stdio.h>
#include <stdlib.h>

#define skip 10

int main(int argc, char** argv) {
    int i, j;
    long result = 0;

    int limit = atoi(argv[1]);

    for (i = 0; i < 10000000; ++i) {
        for (j = 0; j < limit; ++j) {
            if (i + j % skip == 0) {
                continue;
            }
            result  += i + j;
        }
    }

    printf("%lu\n", result);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这里,变量skip是影响程序行为的值的示例.不幸的是,我们需要在每次需要新值时重新编译skip.

让我们看看该程序的另一个版本:

/* program_variable */

#include …
Run Code Online (Sandbox Code Playgroud)

c optimization conditional-compilation c-preprocessor

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

条件分支的落后方更有效吗?把它作为错误处理方面是一个好主意吗?

考虑一个调用另一个函数并检查错误的函数.假设函数CheckError()在失败时返回0,其他数字表示成功.

第一个版本:取得成功分支或落入错误处理代码(位于函数中间).

    CALL   CheckError
    TEST   EAX,EAX    ;check if return value is 0
    JNZ    Normal
ErrorProcessing:
    ...    ;some error processing code here
Normal:
    ...    ;some usual code here
Run Code Online (Sandbox Code Playgroud)

第二个版本在错误时采取分支,或者通过正常路径.错误处理代码位于函数的末尾.

    CALL   CheckError
    TEST   EAX,EAX
    JZ     ErrorProcessing
Normal:
    ...    ;some usual code here
ErrorProcessing:
    ...    ;some error processing code here
Run Code Online (Sandbox Code Playgroud)

这两种方法中哪一个更好?为什么?

就个人而言,我认为第一个代码具有更好的代码结构(更易读和可编程),因为代码是紧凑的.但是,我也认为第二个代码通常具有更好的速度(在无错误的情况下),因为一个未采用的条件跳转需要2-3个时钟周期(可能我在这里太挑剔)少于一个.

无论如何,我发现我测试的所有编译器在编译if语句时都使用第一个模型.例如:

if (GetActiveWindow() == NULL)
{
    printf("Error: can't get window's handle.\n");
    return -1;
}
printf("Succeed.\n");
return 0;
Run Code Online (Sandbox Code Playgroud)

这应编译为(没有任何exe入口例程):

    CALL [GetActiveWindow]    ;if (GetActiveWindow() == NULL)
    TEST …
Run Code Online (Sandbox Code Playgroud)

optimization x86 assembly micro-optimization

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

我可以用我的代码改进分支预测吗?

这是一个对任何平台、语言或编译器都开放的天真的一般性问题。虽然我最好奇的是 Aarch64、C++、GCC。

当在依赖于 I/O 状态的程序流中编写不可避免的分支时(编译器无法预测),并且我知道一种状态比另一种状态更有可能,我如何向编译器表明这一点?

这是否更好

if(true == get(gpioVal))
    unlikelyFunction();
else
    likelyFunction();
Run Code Online (Sandbox Code Playgroud)

比这个?

if(true == get(gpioVal))
    likelyFunction(); // performance critical, fill prefetch caches from this branch
else
    unlikelyFunction(); // missed prediction not consequential on this branch
Run Code Online (Sandbox Code Playgroud)

如果通信协议使更有可能或临界值为真(高)或假(低),这是否有帮助?

c++ optimization gcc branch-prediction likely-unlikely

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

这个构造是什么意思“__builtin_expect(!!(x), 1)”

具体来说,我问的是双“!” 在 __built_in 的参数中。

按照“C”语言,它是双重否定吗?

c gcc gnu clang branch-prediction

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

Visual Studio 编译器在简单 if 语句的分支预测方面有多好?

下面是一些 C++ 伪代码作为示例:

bool importantFlag = false;
for (SomeObject obj : arr) {
    if (obj.someBool) {
        importantFlag = true;
    }
    obj.doSomethingUnrelated();
}
Run Code Online (Sandbox Code Playgroud)

显然,一旦 if 语句评估为 true 并运行内部代码,就没有理由再次执行检查,因为无论哪种方式结果都是相同的。编译器是否足够聪明,能够识别这一点,还是会在每次循环迭代中继续检查 if 语句,并可能再次将 importantFlag 冗余地分配为 true?如果循环迭代次数很大,并且无法跳出循环,则这可能会对性能产生显着影响。

我通常会忽略这些情况,只是将信心寄托在编译器上,但如果能确切地知道它如何处理这些情况,那就太好了。

c++ visual-studio branch-prediction

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