问题:
我有一个基于共同基类的对象家族,需要通过整数值来识别特定的具体类型。
有两种明显的方法可以做到这一点,但是在内存或CPU时间方面都带来了不可接受的开销。由于项目涉及数十亿个对象,即使是最小的开销也会被严重强调,我已经测试过了,这不是过早优化的情况。处理对象所涉及的操作都是微不足道的,虚拟调用的开销极大地降低了性能。
1.对于每个类型实现一个纯虚函数int type(),但不幸的是,这带来了虚拟调用的开销,对于返回静态整数值这样微不足道的事情而言,这是无法接受的。
2.对于每个实例,在构造函数类型中指定一个int type成员,这为这数十亿个对象中的每一个引入了4字节的开销,浪费了内存,污染了缓存等等。
我记得有一段时间有人问过“静态虚拟成员变量”,自然答案都归结为“不行,这没有意义”,然而能够将用户变量放入vtable并有能力为每个特定类型设置其值似乎是解决我的问题的一种非常有效的方法。
这样可以避免上述两种开销,不需要虚拟调用,也没有每个实例的内存开销。唯一的开销是获取vtable的间接寻址,但考虑到该数据的访问频率,它很可能大部分时间都保留在CPU缓存中。
我目前的明显选择是进行“手动OOP”——手动创建vtable以便将必要的“元”数据合并到其中,为每种类型初始化vtable指针,并使用笨拙的语法调用伪“成员”函数。甚至可以完全省略使用vtable指针,并存储id,然后将其用作vtable表的索引,这将更加高效,因为它将避免间接寻址,并将大小缩小,因为我只需要2^14个不同的类型。
如果我能避免重新发明轮子那就太好了。只要它能给我效率保证,我对解决方案并不挑剔。
也许有一种方法可以在vtable中具有我的类型id整数,或者也许有另一种完全不同的方法,这是非常可能的,因为我没有跟上潮流,而C++在过去几年中得到了许多新功能。
当然,这些ID需要是统一和一致的,而不是编译器内部生成的任意值。如果这不是一个要求,我将使用vtable指针值来实现更高效的解决方案,以避免间接寻址。
有什么想法吗?
我有一个基于共同基类的对象家族,需要通过整数值来识别特定的具体类型。
有两种明显的方法可以做到这一点,但是在内存或CPU时间方面都带来了不可接受的开销。由于项目涉及数十亿个对象,即使是最小的开销也会被严重强调,我已经测试过了,这不是过早优化的情况。处理对象所涉及的操作都是微不足道的,虚拟调用的开销极大地降低了性能。
1.对于每个类型实现一个纯虚函数int type(),但不幸的是,这带来了虚拟调用的开销,对于返回静态整数值这样微不足道的事情而言,这是无法接受的。
2.对于每个实例,在构造函数类型中指定一个int type成员,这为这数十亿个对象中的每一个引入了4字节的开销,浪费了内存,污染了缓存等等。
我记得有一段时间有人问过“静态虚拟成员变量”,自然答案都归结为“不行,这没有意义”,然而能够将用户变量放入vtable并有能力为每个特定类型设置其值似乎是解决我的问题的一种非常有效的方法。
这样可以避免上述两种开销,不需要虚拟调用,也没有每个实例的内存开销。唯一的开销是获取vtable的间接寻址,但考虑到该数据的访问频率,它很可能大部分时间都保留在CPU缓存中。
我目前的明显选择是进行“手动OOP”——手动创建vtable以便将必要的“元”数据合并到其中,为每种类型初始化vtable指针,并使用笨拙的语法调用伪“成员”函数。甚至可以完全省略使用vtable指针,并存储id,然后将其用作vtable表的索引,这将更加高效,因为它将避免间接寻址,并将大小缩小,因为我只需要2^14个不同的类型。
如果我能避免重新发明轮子那就太好了。只要它能给我效率保证,我对解决方案并不挑剔。
也许有一种方法可以在vtable中具有我的类型id整数,或者也许有另一种完全不同的方法,这是非常可能的,因为我没有跟上潮流,而C++在过去几年中得到了许多新功能。
当然,这些ID需要是统一和一致的,而不是编译器内部生成的任意值。如果这不是一个要求,我将使用vtable指针值来实现更高效的解决方案,以避免间接寻址。
有什么想法吗?