[英]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對象表示為GLuint
或unsigned 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.2
, OpenGL中的整數應該始終為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.