繁体   English   中英

有效实现64位和32位无符号整数之间的双向映射

[英]Efficient implementation of bidirectional map between 64bit and 32bit unsigned integers

假设我们有两台名为Alice和Bob的机器。 Alice支持使用64位无符号整数进行操作,而Bob仅使用32位无符号整数进行操作。

鲍勃发送爱丽丝请求创建任务。 爱丽丝为每个任务分配唯一的ID,该ID是随机的,但唯一的64位无符号整数。 鲍勃最多可以创建2 ^ 32个任务。

我需要为Bob添加一个功能,使其能够通过ID删除任务。 因此,我需要设置一个代理,以在消息从Alice发送到Bob时用32位uint替换64位单元,并在消息朝相反方向发送时从32位uint恢复64位uint。

问题是我需要使转换非常有效,我只有约10MB的RAM来执行此操作。
有没有已经解决该问题的容器?

更新

社区要求进行澄清,而澄清它的唯一方法是描述现实情况。

因此,我正在研究AOSP中包含的OpenGL转换器库。 总而言之,由于加速原因,它允许将Android系统的渲染(例如在VM内部运行)移动到主机系统。
通过将所有OpenGL命令(来回)从Target(Android)流到主机(即Win8 64位)来完成。

OpenGL对象表示为GLuintunsigned int类型的句柄。 因此,对象的大小和允许的值取决于系统是32位还是64位。

由于大多数Android系统是32位的,而大多数主机系统是64位的,因此会出现问题:在从Android创建OpenGL对象的请求中,Host可以使用无法表示为32bit值的值创建句柄。 但是,出于明显的原因,Android不能要求超过2^32 - 1对象。

我想到的唯一解决方案是设置将64位句柄映射到32位,反之亦然的代理。

产生问题的具体代码: https : //android.googlesource.com/platform/sdk/+/master/emulator/opengl/host/libs/Translator/include/GLcommon/GLutils.h第47行。

更新2

在进一步研究了该问题之后,我发现这不是GLuint的问题(如@KillianDS所述)。 但是它仍然是OpenGL的问题。

有一些函数返回指针,而不是GLuint句柄。 例如eglCreateContext 我需要找到一种在64位主机和32位目标之间交换指针的方法。

更新3

最终,我发现这种具体崩溃与32位和64位计算机之间的句柄转换无关。 这是转换器目标部分中的错误,该错误使用错误的参数调用了错误的函数(glVertexAttribPointerData)。

根据最新的核心OpenGL规范中的table 2.2OpenGL中的整数应该始终为32位宽(ES的规范大致相同)。 据我所知,所有OpenGL名称/句柄(您在问题中也曾说过)都是uint的。 因此,主机和目标上都应为32位。

请注意,正是因为OpenGL具有自己的应符合规范的类型的平台之间, unsigned int的实际位宽可能有所不同。

更新

如果剩下的句柄实际上只是上下文和其他窗口系统调用,我会保持简单,因为我们不是在谈论频繁的操作,也不是在讨论大量的句柄。 通常,每个GPU的每个OpenGL应用程序执行的此类操作不会超过一次,这在任何移动电话上可能都是1。 我认为所有方法中最简单的解决方案是使用数组。 伪代码

class context_creator
{
    std::array<EGLContext, 1000> context_map; //8KB
public:
    context_creator() : context_map{} {}
    uint32_t allocate(...) {
        for(unsigned i = 0; i < context_map.size(); i++) {
            if(!context_map[i]) {
                context_map[i] = eglCreateContext(...);
                return i;
            }
        }
    }
    void deallocate(uint32_t handle) {
        eglDeleteContext(context_map[handle]);
        context_map[handle] = 0;
    }
    //Has to be called in every function where a context is a parameter.
    EGLContext translate(uint32_t handle) const {
        return context_map[handle];
    }
}

请注意,如果0是上下文的有效名称,则此方法将无效。 我真的不知道WGL,但事实并非如此。 这样做的好处是,虽然分配不是有史以来最快的算法,但转换是O(1) ,这是最有可能经常被调用的。

当然,存在变体:

  • 您可以使用更具动态性的容器(例如vector )代替固定大小。
  • 您可以使用哈希表(如std::map ),并且每次调用仅生成唯一索引。 这将消耗更多的内存,因为您还必须存储索引(它在数组中是隐式的),但是如果0是有效的上下文名称,则可以解决此问题。

OpenGL中的uint应该为4字节,即,宽度始终为32位,因此目标和主机上的句柄/名称均应为32位

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM