想象一下,我们有2台名为Alice和Bob的机器。 Alice支持64位无符号整数的操作,而Bob仅支持32位无符号整数。
Bob发送Alice请求以创建任务。对于每个任务,Alice分配唯一ID,该ID是随机但唯一的64位无符号整数。 Bob最多可以创建2 ^ 32个任务。
我需要为Bob添加一项能够按ID删除任务的功能。因此,当消息从Alice转发到Bob时,我需要设置一个代替64位单位的代理,当消息反向时,从32位uint恢复64位uint。
问题在于我需要使转换效率非常高,我只需要大约10MB的RAM来实现这一目标 是否有任何容器已经解决了这个问题?
更新
社区要求澄清,澄清它的唯一方法是描述现实世界的情况。
所以,我正在研究属于AOSP的OpenGL翻译库。总之,出于加速原因,它允许将Android系统的渲染(例如,在VM内部运行)移动到主机系统 它是通过将所有OpenGL命令(前后)从Target(Android)流式传输到主机(即Win8 64bit)来完成的。
OpenGL对象表示为GLuint
或unsigned int
类型的句柄。因此,对象的大小和允许的值取决于系统是32位还是64位。
由于大多数Android系统是32位且大多数主机系统是64位,因此出现了问题:在从Android创建OpenGL对象的请求中,主机可以创建具有不能表示为32位值的值的句柄。但是,由于显而易见的原因,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位机器之间的句柄转换无关。翻译器的Target部分中的一个错误是使用错误的参数调用错误的函数(glVertexAttribPointerData)。
答案 0 :(得分:2)
根据latest core OpenGL spec中的table 2.2
,OpenGL中的uint应始终为32位宽(ES的规格大致相同)。据我所知,所有OpenGL名称/句柄都是uint
的。因此,它在主机和目标上都应该是32位。
请注意,正是因为unsigned int
的实际位宽在OpenGL
具有应符合规范的类型的平台之间可能会有所不同。
如果剩下的句柄实际上只是上下文和其他窗口系统调用,我会保持简单,因为我们不是在谈论频繁的操作,也不是大量的句柄。每个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
是一个有效的上下文名称,它就解决了这个问题。答案 1 :(得分:-1)
OpenGL中的uint应为4个字节,即32位始终为宽度,因此目标和主机上的句柄/名称应为32位