gpt4 book ai didi

c++ - 优化编译时应该知道的if-else,但信息在不同的项目中

转载 作者:行者123 更新时间:2023-11-28 04:26:36 25 4
gpt4 key购买 nike

如何使用户能够定义模板功能的“行为模式”doIt(a,b)将来自另一个用户定义的变量/函数 op并且优化 if-else?

这是一个有效的 MCVE。
我的 VS 解决方案有 2 个项目。 pj1 是我的图书馆。 pj2 是用户的项目。

A_pj1.h

#pragma once
template<int T>class BoolT{public:
static bool op;
};
template<int T> bool BoolT<T>::op=true; //by default, true=+, false=-
template<int i> int doIt(int a,int b){
if(BoolT<i>::op){
return a+b;
}else{ return a-b;}
}

A_pj2_UserDefine.h

#pragma once
#include "A_pj1.h"
inline void A_pj2_UserDefine_Reg(){
BoolT<2>::op=false; //override default value;
}

A_pj2_main.cpp

#include "A_pj2_UserDefine.h"
#include <iostream>
int main(){
A_pj2_UserDefine_Reg();
int s1=doIt<1>(3,2); //= 5 (correct)
int s2=doIt<2>(3,2); //= 1 (correct)
std::cout << s1<<" "<<" "<<s2<<std::endl;
int asfasd=0;
}

(编辑)这是反汇编(优化版):-

int s2=doIt<2>(3,2);
std::cout << s1<<" "<<" "<<s2<<std::endl;
00B61620 mov ecx,dword ptr [_imp_?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A (0B6B0A8h)]
int s1=doIt<1>(3,2); //:
00B61626 xor eax,eax
00B61628 cmp byte ptr [BoolT<1>::op (0B6E001h)],al
int s2=doIt<2>(3,2);
std::cout << s1<<" "<<" "<<s2<<std::endl;
00B6162E push offset std::endl<char,std::char_traits<char> > (0B61530h)
00B61633 push 1
int s1=doIt<1>(3,2); //:
00B61635 setne al
A_pj2_UserDefine_Reg();
00B61638 mov byte ptr [BoolT<2>::op (0B6E000h)],0
int s2=doIt<2>(3,2);
std::cout << s1<<" "<<" "<<s2<<std::endl;
00B6163F push offset string " " (0B6B220h)
00B61644 push offset string " " (0B6B220h)
int s1=doIt<1>(3,2); //:
00B61649 lea eax,[eax*4+1]
int s2=doIt<2>(3,2);
std::cout << s1<<" "<<" "<<s2<<std::endl;
00B61650 push eax
00B61651 call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (0B6B0B4h)]
00B61657 push eax
00B61658 call std::operator<<<std::char_traits<char> > (0B61310h)
00B6165D add esp,8
00B61660 push eax
00B61661 call std::operator<<<std::char_traits<char> > (0B61310h)
00B61666 add esp,8
00B61669 mov ecx,eax
00B6166B call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (0B6B0B4h)]
00B61671 mov ecx,eax
00B61673 call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (0B6B0B8h)]
int asfasd=0;
}
00B61679 xor eax,eax
00B6167B ret

问题

doIt(a,b)经常被调用(每秒 >60000 次)。
我很好奇 if(BoolT<i>::op)可以优化掉。
If-condition 不利于流水线计算。

这是我的程序行为,可能会有所帮助:-

  • 访问-写入 BoolT<2>::op总是只出现在程序的开头(例如 A_pj2_UserDefine_Reg() )。
  • 功能查询BoolT<2>::op (直接和间接)几乎总是只发生在项目中 pj2 .
  • 用户不能编辑pj1
  • 在真实案例中,除了A_pj2_main.cpp , 有很多 .cpp那个电话 pj1doIt<>() .这是包含图:-

enter image description here

我糟糕的解决方案

B_pj1.h

#pragma once
template<int i> bool op(){return true;}
template<int i> int doIt(int a,int b){
if(op<i>()){
return a+b;
}else{ return a-b;}
// return a+b;
}

B_pj2_UserDefine.cpp

#include "B_pj1.h"
template<> bool op<2>(){return false;}

B_pj2_main.cpp

#include <iostream>
#include "B_pj1.h"
int main(){
int s1=doIt<1>(3,2); //:
int s2=doIt<2>(3,2);
std::cout << s1<<" "<<" "<<s2<<std::endl;
int asfasd=0;
}

这个程序是错误的。 (引用:Storing C++ template function definitions in a .CPP file)

Error LNK2005 "bool __cdecl op<2>(void)" (??$op@$01@@YA_NXZ) already defined in B_pj2_UserDefine.obj

最佳答案

您当前的代码没问题。 If 条件只会在每次采用不同的分支时损害流水线计算。当该标志只写入一次时,分支预测就做得很好。

无论如何,您的问题的常见解决方案是 C 预处理器宏。技术上可以用例如解决if constexpr 但在实践中,这将要求库从用户的项目中#include 一些东西,而大多数库作者不想支持这种用例。

如果您愿意使库仅包含标题,也可以使用模板来解决,但更复杂。由于例如,我尽量避免跨库边界的模板。编译时间开销。

关于c++ - 优化编译时应该知道的if-else,但信息在不同的项目中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54176275/

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