在 C++ 中,我想编写一个类似于脚本语言的应用程序:
在“设置时间”期间的一些输入中,它将在一个大的全局数组上定义每个变量所在的位置,并在不同的数组上定义函数的顺序( “LogicElement”)调用(包括它们的参数,如要使用的变量)。
一种实现可能如下所示:
class LogicElement_Generic
{
public:
virtual void calc() const = 0;
};
class LogicElement_Mul : public LogicElement_Generic
{
int &to;
const int &from1;
const int &from2;
public:
LogicElement_Mul( int &_to, const int &_from1, const int &_from2 ) : to(_to), from1(_from1), from2(_from2)
{}
void calc() const
{
to = from1 * from2;
}
};
char globalVariableBuffer[1000]; // a simple binary buffer
LogicElement_Generic *le[10];
int main( void )
{
// just a demo, this would be setup from e.g. an input file:
int *to = (int*)globalVariableBuffer;
int *from1 = (int*)(globalVariableBuffer + sizeof(int));
int *from2 = (int*)(globalVariableBuffer + 2*sizeof(int));
*from1 = 2;
*from2 = 3;
le[0] = new LogicElement_Mul( *to, *from1, *from2 );
// doing all calculations:
// finally it would be a loop iterating over all calculation functions,
// over and over again - the area in the code where all the resources
// would be burned...
le[0]->calc();
return *to;
}
尽管按预期工作,但查看创建的程序集:
78 .section .text._ZNK16LogicElement_Mul4calcEv,"axG",@progbits,_ZNK16LogicElement_Mul4calcEv,comdat
79 .align 2
80 .weak _ZNK16LogicElement_Mul4calcEv
82 _ZNK16LogicElement_Mul4calcEv:
83 .LFB6:
17:.../src/test.cpp **** void calc() const
84 .loc 1 17 0
85 .cfi_startproc
86 0000 55 pushq %rbp
87 .LCFI6:
88 .cfi_def_cfa_offset 16
89 .cfi_offset 6, -16
90 0001 4889E5 movq %rsp, %rbp
91 .LCFI7:
92 .cfi_def_cfa_register 6
93 0004 48897DF8 movq %rdi, -8(%rbp)
18:.../src/test.cpp **** {
19:.../src/test.cpp **** to = from1 * from2;
94 .loc 1 19 0
95 0008 488B45F8 movq -8(%rbp), %rax
96 000c 488B4008 movq 8(%rax), %rax
97 0010 488B55F8 movq -8(%rbp), %rdx
98 0014 488B5210 movq 16(%rdx), %rdx
99 0018 8B0A movl (%rdx), %ecx
100 001a 488B55F8 movq -8(%rbp), %rdx
101 001e 488B5218 movq 24(%rdx), %rdx
102 0022 8B12 movl (%rdx), %edx
103 0024 0FAFD1 imull %ecx, %edx
104 0027 8910 movl %edx, (%rax)
20:.../src/test.cpp **** }
105 .loc 1 20 0
106 0029 5D popq %rbp
107 .LCFI8:
108 .cfi_def_cfa 7, 8
109 002a C3 ret
110 .cfi_endproc
查看装配线 95 .. 104,您可以看到对于每个变量,使用了三个间接方法。
由于这部分代码(calc() 方法)最终会被非常快速地调用,因此我希望尽可能少地使用 CPU 周期和内存带宽(通过通用 C/C++)。
我还希望实现(上面的代码中未显示)拥有两个具有完全相同布局的变量缓冲区,以便能够以多线程方法进行双缓冲以限制必要的锁(确切的实现细节对于这个问题)。
所以最大的问题是:
- 如何更改架构以减少 calc() 中的内存间接数量?
(我希望只有两个:一个获取变量数组中的偏移地址,另一个获取变量本身 - 但我的实验将上面的代码更改为使用偏移使事情变得更糟!) - 有没有更好的方法来设置类,从而设置 LogicElements 的数组,以便调用计算方法将使用最少的资源?