gpt4 book ai didi

自定义 "non-traditional"多态性实现

转载 作者:太空宇宙 更新时间:2023-11-04 04:45:28 26 4
gpt4 key购买 nike

我一直在寻找一种自定义多态解决方案来提高二进制兼容性。问题是指针成员在不同平台上的大小不同,因此即使是“静态”宽度成员也会被推来推去产生二进制不兼容的布局。

按照我的理解,大多数编译器都以类似的方式实现 v 表:

    __________________
| | | |
|0| vtable* | data | -> ->
|_|_________|______|

例如v 表被放置为对象的第一个元素,在多重继承的情况下,继承的类按顺序与适当的填充对齐。

所以,我的想法如下,将所有 v 表(以及所有不同的“平台宽度”成员)“放在后面”:

       __________________
| | | |
<- | vtable* |0| data | ->
|_________|_|______|

这样,0 的布局右侧(第一个数据成员的对齐边界)仅由具有显式和可移植大小和对齐方式的类型组成(因此它可以保持统一),同时您仍然可以可移植地导航通过 v 表和其他指针成员使用具有平台宽度跨度的索引。此外,由于左侧的所有成员都具有相同的大小和对齐方式,这可以减少布局中额外填充的需要。

自然地,这意味着“this”指针将不再指向对象的开头,而是会随着每个类的不同而有所不同。这意味着“new”和“delete”必须进行调整才能使整个方案正常工作。这是否会产生可衡量的负面影响,考虑到无论如何,在访问成员时都会发生偏移量计算?

我的问题是是否有经验丰富的人可以指出使用这种方法的潜在注意事项。

编辑:

我做了一个快速测试以确定额外的偏移量计算是否会对虚拟调用的性能产生不利影响(是的是的,我知道这是 C 问题中的 C++ 代码,但我没有纳秒分辨率计时器C,加上整点以便与现有的多态性实现进行比较):

class A;
typedef void (*foo)(A*);

void bar(A*) {}

class A {
public:
A() : a(&bar) { }
foo a;
virtual void b() {}
};

int main() {
QVector<A*> c;
int r = 60000000;

QElapsedTimer t;
for (int i = 0; i < r; ++i) c.append(new A);
cout << "allocated " << c.size() << " object in " << (quint64)t.elapsed() << endl;

for (int count = 0; count < 5; ++count) {
t.restart();
for (int i = 0; i < r; ++i) {
A * ap = c[i]; // note that c[i]->a(c[i]) would
ap->a(ap); // actually result in a performance hit
}
cout << t.elapsed() << endl;

t.restart();
for (int i = 0; i < r; ++i) {
c[i]->b();
}
cout << t.elapsed() << endl;
}
}

在测试了 6000 万个对象(7000 万在我当前使用的 32 位编译器上分配失败)之后,调用常规虚函数和通过非对象中的第一个元素(因此需要额外的偏移量计算),即使在函数指针的情况下,内存地址也被传递了两次,例如pass 找到a的偏移量,然后传入a)。在 Release模式下,两个函数的时间是相同的(6000 万次调用为 +/- 1 纳秒),而在 Debug模式下,函数指针实际上始终快 1%(也许函数指针需要的资源比虚函数少)。

在分配和删除时调整指针的开销似乎也几乎可以忽略不计,并且完全在误差范围内。这是意料之中的,考虑到它应该只增加一个已经在寄存器上的值的一个立即值,这在我打算定位的平台上应该需要一个周期。

最佳答案

仅供引用,vtable 的地址位于对象的第一个 DWORD/QWORD,而不是表本身。 vtable 在同一类/结构的对象之间共享。

顺便说一下,平台之间具有不同的 vtable 大小不是问题。不兼容的平台无法执行其他平台的 native 代码,要使二进制翻译正常工作,模拟器需要了解原始架构。

与当前实现相比,您的解决方案的主要缺点是性能和复杂性。

关于自定义 "non-traditional"多态性实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21431428/

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