gpt4 book ai didi

c++ - 未到达的案例会影响切换案例的性能

转载 作者:行者123 更新时间:2023-12-02 09:50:26 25 4
gpt4 key购买 nike

在C++中,我有一个内联函数,其中包含一个switch-case语句。我发现,当对某些特定案例分支进行编程时,即使在运行时从未碰到特定案例,该程序的时间成本也显着增加。

代码示例如下所示:

#include <stdio.h>
#include <iostream>
#include <sys/time.h>
#include <string>

using namespace std;

enum Types {
T0 = 0, T1, T2, T3, T4, T5, T6, T7, T8, T9, TS, TA, TB, TC
};

int64_t special(int64_t num, string str) {
char buf[16];
buf[0] = (num % 10) + '0';
buf[1] = (num % 10) + '0';
buf[2] = str.c_str()[0];
return atoi(buf);
}

inline int64_t common(int64_t base, int64_t num) {
return num + base;
}

inline int64_t myfunc(Types t, int64_t num) {
string str;
switch (t) {
case T0:
return 0;
break;
#define CASE_TYPE(tv, base) \
case tv: \
return common(base, num); \
break;
CASE_TYPE(T1, 1)
CASE_TYPE(T2, 2)
CASE_TYPE(T3, 3)
CASE_TYPE(T4, 4)
CASE_TYPE(T5, 5)
CASE_TYPE(T6, 6)
CASE_TYPE(T7, 7)
CASE_TYPE(T8, 8)
CASE_TYPE(T9, 9)
#undef CASE_TYPE
case TS:
// Comment out the following 3 lines increases performance
str = string((char*)&num, 4);
return special(num, str);
break;
// Comment out the above 3 lines increases performance
case TA:
case TB:
case TC:
return 0;
break;
}
return 0;
}

static const int LoopNum = 1000000000;

static inline int64_t now() {
struct timeval tv;
gettimeofday(&tv, NULL);
return (int64_t)tv.tv_sec * 1000 + (int64_t)tv.tv_usec / 1000;
}


// execution command line: ./test 1 1
int main(int argc, char *argv[])
{
Types t = (Types)atoi(argv[1]); // t = T1
int64_t num = (int64_t)atoi(argv[2]); // t = 1
int64_t total = 0;
int64_t start = now();
for (int i = 0; i < LoopNum; i++) {
total += myfunc(t, num);
}
cout << "Time Cost: " << now() - start << " ms" << endl;
cout << "Result: " << total << endl;
return 0;
}

在此程序中,当 case TS块中的行被注释掉时,性能将大大提高:
  • 使用 case TS块:时间成本= 2250毫秒
  • 没有 case TS块:时间成本= 1492毫秒

  • 程序使用命令 g++ -o test -O2 test.cpp && ./test 1 1编译和执行。使用此命令,程序中的变量值为 t = T1num = 1

    Windows Subsystem for linux (Ubuntu 18.04)上使用 g++ 7.4.0测试。

    令人困惑的是,这个问题并不总是会出现。我不知道如何编写这样的代码(但是上面的示例确实出现了这个问题)。

    根据我的测试,似乎在以下某些情况下会出现问题:
  • 特殊情况中,程序很复杂。例如。当程序包含远程进程调用时。
  • 特定于的个案不是最后一个个案,或者个案值不是枚举中的最大值。


  • 我真的不知道这种情况如何发生以及如何避免。任何人都可以给一个地方吗?该机制或替代方法都将有所帮助。谢谢。

    最佳答案

    查看Compiler Explorer上的反汇编,不同之处在于,当注释掉case TS的代码时,您将删除对本地str字符串变量的所有使用。编译器将其完全删除,生成的代码更加简单(因为没有可能调用构造函数或析构函数,尤其是删除以释放字符串的内存)。简化的代码足够小以适合处理器的环路流检测器(LSD)。由于重复指令始终驻留在指令队列中,因此LSD可以极大地提高紧密循环的性能,从而避免使用前端管道。

    关于c++ - 未到达的案例会影响切换案例的性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60114903/

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