C++ 使用C++;用于编译时函数生成的模板或宏
我有一个在嵌入式系统上运行的代码,它必须运行得非常快。我知道C和宏,这个特殊的项目主要是用C编码的,但是它也使用C++的模板[越来越多]。有一个内联函数:C++ 使用C++;用于编译时函数生成的模板或宏,c++,templates,macros,inline,cuda,C++,Templates,Macros,Inline,Cuda,我有一个在嵌入式系统上运行的代码,它必须运行得非常快。我知道C和宏,这个特殊的项目主要是用C编码的,但是它也使用C++的模板[越来越多]。有一个内联函数: inline my_t read_memory(uint32 addr) { #if (CURRENT_STATE & OPTIMIZE_BITMAP) return readOptimized(addr); #else return MEMORY[addr]; #endif } 此函数根据当前状态和位图
inline my_t read_memory(uint32 addr) {
#if (CURRENT_STATE & OPTIMIZE_BITMAP)
return readOptimized(addr);
#else
return MEMORY[addr];
#endif
}
此函数根据当前状态和位图(指示是否在特定状态下使用优化)以优化方式或常规方式读取内存
#define STATE_A 0x0001
#define STATE_B 0x0010
#define STATE_C 0x0100
#define STATE_D 0x1000
#define OPTIMIZE_BITMAP 0x1010 // optimize states d and b
在执行过程中(好的,编译),我试图重新定义当前的_状态,如下所示:
int main(){
#define CURRENT_STATE STATE_A
do_a();
#undef CURRENT_STATE
#define CURRENT_STATE STATE_B
do_b();
....
}
所有do_X()函数都进行read_memory()调用。我无法使这种方法起作用。当我使用#警告语句时,当前状态的值总是state_A。这不是我的问题,尽管如果你能帮我,我会非常高兴。所以,我的问题是,有没有一种方法可以使用模板而不是宏来完成这类工作
更多信息:我必须使用内联函数,因为我无法导出内存[],而这是一个库函数。我真的不想修改函数原型(比如read_memory()…),但它可以。还有,请原谅我的默默无闻
非常感谢,我认为您可能误解了编译器(或者更确切地说,预处理器)对#定义的作用 您的示例(下面引用)没有用处,因为在#define和#undef之间没有使用当前的#状态。预处理器此时不是在“执行”代码,也不是在内联扩展do_a()#定义和宏展开只能按照源代码中的行顺序进行
#define CURRENT_STATE STATE_A
do_a();
#undef CURRENT_STATE
这是一个基于预处理器的解决方案,如果模板让你感到恐惧的话。让我们假设do_a()
应该使用优化版本
inline my_t read_memory(uint32 addr)
{
return MEMORY[addr];
}
inline my_t read_memory_optimized(uint32 addr)
{
return readOptimized(addr);
}
现在,创建DO_CONFIG.H
#if defined(DO_A) || (defined(DO_C) || ...)
#define READ_MEMORY read_memory_optimized
#else
#define READ_MEMORY read_memory
在DO_A.C
中,将其添加到顶部
#define DO_A
#include DO_CONFIG.H
…并使用
x=READ\u MEMORY(addr)
代替x=READ\u MEMORY(addr)
。要从优化转换为非优化,只需更改DO_CONFIG.H
我认为您可能误解了编译器(或者更确切地说,预处理器)对#定义的作用
#if defined(DO_A) || (defined(DO_C) || ...)
#define READ_MEMORY read_memory_optimized
#else
#define READ_MEMORY read_memory
您的示例(下面引用)没有用处,因为在#define和#undef之间没有使用当前的#状态。预处理器此时不是在“执行”代码,也不是在内联扩展do_a()#定义和宏展开只能按照源代码中的行顺序进行
#define CURRENT_STATE STATE_A
do_a();
#undef CURRENT_STATE
这是一个基于预处理器的解决方案,如果模板让你感到恐惧的话。让我们假设do_a()
应该使用优化版本
inline my_t read_memory(uint32 addr)
{
return MEMORY[addr];
}
inline my_t read_memory_optimized(uint32 addr)
{
return readOptimized(addr);
}
现在,创建DO_CONFIG.H
#if defined(DO_A) || (defined(DO_C) || ...)
#define READ_MEMORY read_memory_optimized
#else
#define READ_MEMORY read_memory
在DO_A.C
中,将其添加到顶部
#define DO_A
#include DO_CONFIG.H
…并使用
x=READ\u MEMORY(addr)
代替x=READ\u MEMORY(addr)
。要从优化切换到非优化,只需更改DO_CONFIG.H
内联函数将在转换单元中声明它的点处解析一次,并使用该点处宏的状态。使用不同定义的宏多次调用函数不会更改函数的定义
#if defined(DO_A) || (defined(DO_C) || ...)
#define READ_MEMORY read_memory_optimized
#else
#define READ_MEMORY read_memory
但是,您可以使用模板执行此操作,如果您将“当前状态”作为模板参数传递,则可以在每个调用点使用不同的实例化:
template<unsigned state>
inline my_t read_memory(uint32 addr) {
if(state & OPTIMIZE_BITMAP)
return readOptimized(addr);
else
return MEMORY[addr];
}
int main(){
read_memory<STATE_A>(some_addr);
read_memory<STATE_B>(some_addr);
....
}
模板
内联我的读取内存(uint32地址){
if(状态和优化\u位图)
返回readOptimized(addr);
其他的
返回存储器[addr];
}
int main(){
读存储器(一些地址);
读存储器(一些地址);
....
}
编译器将意识到
state&OPTIMIZE\u BITMAP
是一个常量,并针对每个模板实例化优化出if
的一个或另一个分支。内联函数将在转换单元中声明它的点处解析一次,并将使用该点处宏的状态。使用不同定义的宏多次调用函数不会更改函数的定义
但是,您可以使用模板执行此操作,如果您将“当前状态”作为模板参数传递,则可以在每个调用点使用不同的实例化:
template<unsigned state>
inline my_t read_memory(uint32 addr) {
if(state & OPTIMIZE_BITMAP)
return readOptimized(addr);
else
return MEMORY[addr];
}
int main(){
read_memory<STATE_A>(some_addr);
read_memory<STATE_B>(some_addr);
....
}
模板
内联我的读取内存(uint32地址){
if(状态和优化\u位图)
返回readOptimized(addr);
其他的
返回存储器[addr];
}
int main(){
读存储器(一些地址);
读存储器(一些地址);
....
}
编译器会意识到
state&OPTIMIZE\u BITMAP
是一个常量,并为每个模板实例化优化出if
的一个或另一个分支。为什么要使用模板来做这件事?这是我在编译时决策时可以想到的,因为我不想在运行时决定。但我是开放的。好吧,是什么让你认为运行时决策会太慢?你描述过这样的事情吗?我们都希望我们的代码运行“非常快”,99.99%的时间都是这样,而不需要使用外来的宏或模板。这是cuda代码,我被告知要尽量减少if语句,但也许我必须首先对其进行分析,感谢下面的评论,perreal正在编写一个库和do_X()
函数实际上是用户提供的代码。为什么要使用模板来执行此操作?这是我在编译时决策时可以想到的,因为我不想在运行时决策。但我是开放的。好吧,是什么让你认为运行时决策会太慢?你描述过这样的事情吗?我们都希望我们的代码运行“非常快”,99.99%的时间都是这样,而不需要使用外来的宏或模板。这是cuda代码,我被告知要尽量减少if语句,但也许我必须首先对其进行分析,感谢下面的评论,perreal正在编写一个库和do_X()
函数实际上是用户提供的代码。@perreal。你在问问题。真聪明!所以,也许有一些