【发布时间】:2012-08-06 00:17:56
【问题描述】:
我想在 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 的数组,以便调用计算方法将使用最少的资源?
【问题讨论】:
-
测量性能的关键步骤;实际测量性能。我在这里看不到测试结果。顺便说一句;为什么要存储对
ints 的引用?以无效数据结束的好方法,而您却一无所获。 -
每个变量的 3 个间接寻址实际上对于解释器来说非常好。感谢上帝,没有多种类型。
-
@Ed S.:您说得对,必须确定关键部件的测量值。但这里的情况略有不同:这是一个全局设计/架构问题,而不是局部优化问题。我们应该将这些数字与什么进行比较?原生实现?我对偏移量的可悲尝试?感谢您提供的参考资料,我会再次尝试不使用它们
-
@delnan:会有多种类型 - 但它们会在设置时被知道并导致不同的
calc()函数/方法。 (很高兴知道 3 很好 - 但我知道它可以用更少的东西来完成。但是我如何使用像 C 或 C++ 这样的高级语言来实现这一点?!?)
标签: c++ algorithm class optimization