簡體   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