主頁 > 移動端開發 > 您可以使用C行內匯編來對齊指令嗎?(沒有編譯器優化)

您可以使用C行內匯編來對齊指令嗎?(沒有編譯器優化)

2022-04-27 19:29:54 移動端開發

我必須做一個大學專案,我們必須使用快取優化來提高給定代碼的性能,但我們不能使用編譯器優化來實作它。

我閱讀參考書目的想法之一是將基本塊的開頭與行快取大小對齊。但是你能做這樣的事情嗎:

asm(".align 64;")
for(int i = 0; i<N; i  )
... (whole basic block)

為了實作我正在尋找的東西?我不知道是否可以在指令對齊方面做到這一點。我已經看到了一些類似_mm_malloc實作資料對齊的技巧,但沒有任何指令。誰能給我一些關于此事的資訊?

uj5u.com熱心網友回復:

TL:DR: 這可能不是很有用(因為現代 x86 帶有 uop 快取通常不關心代碼對齊1),但在do{}while()回圈前“作業” ,它可以直接編譯為具有相同布局的 asm,在回圈的實際頂部之前沒有任何回圈設定(序言)指令。(向后分支的目標)。

一般來說,https://gcc.gnu.org/wiki/DontUseInlineAsm尤其是永遠不要asm("foo");在函式中使用 GNU C Basic,但在除錯模式下(-O0默認,也就是禁用優化)每個陳述句(包括asm();)編譯成一個單獨的塊asm 按源順序排列。因此,您的情況實際上并不需要 Extendedasm(".p2align 4" ::: "memory")來訂購 asm 陳述句 wrt。記憶體操作。(同樣在最近的 GCC 中,對于具有非空模板字串的 Basic asm,記憶體破壞器是隱含的)。在最壞的情況下,啟用優化后,填充可能會變得無用并損害性能,但不會影響正確性,這與asm().


這實際上是如何編譯的

這并不完全有效;Cfor回圈在asm 回圈之前編譯為一些 asm 指令特別是for(a;b;c)在陳述句中使用帶有一些首次迭代前初始化的回圈時a您當然可以在源代碼中將其提取出來,但 GCC 的編譯回圈-O0策略是在底部進入帶有 to 條件的回圈。whileforjmp

jmp僅此一項只是一條小的(2 位元組)指令,因此在此之前對齊會將回圈頂部置于可能的指令獲取塊的開頭附近,如果這是一個瓶頸,它仍然可以獲得大部分好處。(或者在一組新的 uop-cache 行的開頭附近 Sandybridge-family x86 其中 32 位元組邊界是相關的。甚至是 64 位元組 I-cache 行,盡管這很少相關并且可能導致執行大量 NOP達到那個邊界。和臃腫的代碼大小。)

void foo(register int *p)
{
    // always use .p2align n or .balign 1<<n so it's unambiguous across targets like MacOS vs. Linux, never .align
    asm("   .p2align 5 # from inline asm");
    for (register int *endp = p   102400; p<endp ; p  ) {
        *p  = 123;
    }
}

在Godbolt 編譯器資源管理器上編譯如下請注意,我使用的方式register意味著盡管進行了除錯構建,但我得到了不可怕的 asm,并且不必合并p p <= endp減少*(p ) = 123;存盤/重新加載開銷(因為對于register本地人來說首先沒有任何開銷)。而且我使用了指標增量/比較來保持 asm 簡單,并且更難除錯模式去優化為更多浪費的 asm 指令。

# GCC11.3 -O0 (the default with no options, except for -masm=intel added by Godbolt)
foo:
        push    rbp
        mov     rbp, rsp
        push    rbx                        # GCC stupidly picks a call-preserved reg it has to save
        mov     rax, rdi
           .p2align 5 # from inline asm
        lea     rbx, [rax 409600]          # endp = p 102400
        jmp     .L2                        # jump to the p<endp condition before the first iteration
## The actual top of the loop.  9 bytes past the alignment boundary
.L3:                                       # do{
        mov     edx, DWORD PTR [rax]
        add     edx, 123
        mov     DWORD PTR [rax], edx         # A memory destination add dword [rax], 123  would be 2 uops for the front-end (fused-domain) on Intel, vs. 3 for 3 separate instructions.
        add     rax, 4                       # p  
.L2:
        cmp     rax, rbx
        jb      .L3                        # }while(p<endp)
        nop
        nop                                # These aren't for alignment, IDK what this is for.
        mov     rbx, QWORD PTR [rbp-8]     # restore RBX
        leave                              # and restore RBP / tear down stack frame
        ret

這個回圈長 5 微秒(假設 cmp/JCC 的宏融合),因此如果一切順利,可以在 Ice Lake 或 Zen 上以每次迭代運行 1 個回圈。(每個周期加載/存盤 1 個 dword 的記憶體帶寬并不多,因此即使它不適合 L3 cahce,它也應該跟上一個大陣列。)或者在 Haswell 上,例如,每次迭代可能 1.25 個周期,或者由于回圈緩沖效應可能會更糟

如果你在 Godbolt 上使用“二進制”輸出模式,你可以看到這lea rbx, [rax 409600]是一個 7 位元組的指令,whilejmp .L2是 2 個位元組,回圈頂部的地址是0x401149,即 16 位元組的 fetch-block 中的 9 個位元組, 在獲取該大小的 CPU 上。我對齊了 32,所以它只浪費了與這個塊關聯的第一個 uop 快取行中的 2 個 uop,所以我們在 32 位元組塊方面仍然相對較好。

(Godbolt“二進制”模式編譯并鏈接成可執行檔案,并在objdump -d其上運行。這也讓我們看到.p2align指令擴展為某個寬度的 NOP 指令,或者如果它必須跳過超過 11 個位元組,則擴展為一個以上,默認x86-64 的 GAS 的最大 NOP 寬度。請記住,每次控制通過此 asm 陳述句時,必須獲取這些 NOP 指令并通過管道,因此函式內部的大量對齊對它和 I- 來說都是一件壞事快取足跡。)

一個相當明顯的轉換在.p2align. (如果您好奇,請參閱所有這些源版本的 Godbolt 鏈接中的 asm)。

    register int *endp = p   102400;
    asm("   .p2align 5 # from inline asm");
    for ( ; p < endp ; p  ) {
        *p  = 123;
    }

或者while (p < endp){... ; p }也可以解決問題。asm 回圈的頂部變為以下內容,回圈條件只有 2 個位元組jmp所以這是相當不錯的,并且獲得了大部分好處。

        lea     rbx, [rax 409600]
           .p2align 5 # from inline asm
        jmp     .L5                       # 2-byte instruction
.L6:

或許可以用for(foo=bar, asm(".p2align 4) ; p<endp ; p ). 但是,如果您在陳述句的第一部分宣告一個變數for,逗號運算子將無法讓您潛入單獨的陳述句。

要真正對齊 asm 回圈,我們可以將其寫為do{}while.

    register int *endp = p   102400;
    asm("   .p2align 5 # from inline asm");
    do {
        *p  = 123;
        p  ;
    }while(p < endp);
        lea     rbx, [rax 409600]
           .p2align 5 # from inline asm
.L8:                                     # do{
        mov     edx, DWORD PTR [rax]
        add     edx, 123
        mov     DWORD PTR [rax], edx
        add     rax, 4
        cmp     rax, rbx
        jb      .L8                      # while(p<endp)

一開始沒有jmp,回圈內沒有分支目標標簽。(如果您想嘗試-falign-labels=32讓 GCC 為您填充而不將 NOP放入回圈中,這很有趣。見下文:-falign-loops 不起作用-O0。)

由于我對非零大小進行硬編碼,因此p == endp在第一次迭代之前不會運行任何檢查。如果該長度是運行時變數,例如函式 arg,則可以if(n==0) return;在回圈之前執行。或者更一般地說,如果不能證明它總是運行至少一次迭代,則在編譯啟用優化的或回圈時將回圈放在GCC 中。ifforwhile

  if(n!=0) {
      register int *endp = p   n;
      asm (".p2align 4");
      do {
          ...
      }while(p!=endp); 
  }

讓 GCC 為您執行此操作:-falign-loops=16不起作用-O0

GCC-O2啟用-falign-loops=16:11:8或類似的東西(如果跳過少于 11 個位元組,則按 16 對齊,否則按 8 對齊)。這就是為什么 GCC 使用兩個.p2align指令的序列,第一個有填充限制(參見 GAS 手冊)。

        .p2align 4,,10            # what GCC does on its own
        .p2align 3

但是 using-falign-loops=16-O0. 似乎 GCC -O0 不知道什么是回圈。:P

但是,GCC甚至-falign-labels-O0. 但不幸的是,這適用于所有標簽,包括內部回圈內的回圈入口點。 神箭

# gcc -O0 -falign-labels=16
## from compiling endp=...; asm(); while() {}
        lea     rbx, [rax 409600]              # endp = ...
           .p2align 5 # from inline asm
        jmp     .L5
        .p2align 4                         # from GCC itself, pads another 14 bytes to an odd multiple of 16 (if you didn't remove the manual .p2align 5)
.L6:
        mov     edx, DWORD PTR [rax]
        add     edx, 123
        mov     DWORD PTR [rax], edx
        add     rax, 4
        .p2align 4                         # from GCC itself: one 5-byte NOP in this particular case
.L5:
        cmp     rax, rbx
        jb      .L6

將 NOP 放在最內層回圈中比在現代 x86 CPU 上錯開它的開始更糟糕。

回圈沒有這個問題do{}while(),但在這種情況下,它似乎也可以用來asm()在那里放置對齊指令。

(我使用了如何從 GCC/clang 程式集輸出中洗掉“噪音”?編譯選項以在不過濾掉指令的情況下最大限度地減少混亂,其中包括.p2align. 如果我只是想看看行內匯編的去向,我可以asm("nop #hi mom")使用它在過濾掉指令后可見。)


如果您可以使用行內匯編,但必須使用反優化除錯模式進行編譯,那么在具有輸入/輸出約束的行內匯編中重寫整個內部回圈可能會大大加快速度。但不要真的這樣做;很難做到正確,在現實生活中,普通人只會啟用優化作為第一步。)


腳注 1:代碼對齊對現代 x86 幫助不大,可能對其他人有幫助

即使您確實對齊了向后分支的目標(而不僅僅是一些回圈序言),這也不太可能有幫助;現代 x86 CPU 帶有 uop 快取(Sandybridge 系列和 Zen 系列)和回圈緩沖區(Nehalem 和后來的 Intel)不太關心回圈對齊。

它可以在較舊的 x86 CPU 或其他一些 ISA 上提供更多幫助;只有 x86 很難解碼,以至于 uop 快取是一回事 (您實際上并沒有指定 x86,但目前大多數人在他們的臺式機/筆記本電腦中使用 x86 CPU,所以我假設。)

分支目標對齊有幫助(尤其是回圈頂部)的主要原因是,當 CPU 獲取包含目標地址的 16 位元組對齊塊時,該塊中的大部分機器代碼將它之后,因此是即將運行另一個迭代的回圈體。(分支目標之前的位元組在該提取周期中被浪費)。

但是最壞的未對齊情況(除非有其他奇怪的影響)只會花費您 1 個額外的前端提取周期來獲得回圈體中的更多指令。(例如,如果回圈的頂部有一個以 結尾的地址0xf,那么它是 16 位元組塊的最后一個位元組,則包含該位元組的對齊 16 位元組塊將只包含最后一個有用的位元組。)這可能是一個單位元組指令cdq,但管道通常是 4 條指令寬,或更多。

(或者在早期的英特爾 P6 系列時代,在提取、預解碼(長度查找)和解碼之間存在緩沖區之前,為 3 寬。如果回圈的其余部分有效解碼并且平均指令長度很短,則緩沖可以隱藏氣泡. 但是解碼仍然是一個重要的瓶頸,直到 Nehalem 的回圈緩沖區可以為一個小回圈(幾十個 uops)回收解碼結果(uops)。Sandybridge 系列添加了一個 uop 快取來快取包含多個被呼叫的函式的大回圈David Kanter 對SnB的深入研究有很好的框圖,另見https://www.agner.org/optimize/特別是 Agner 的 microarch pdf。

即使這樣,它也只有在前端(指令獲取/解碼)帶寬是一個問題時才有幫助,而不是一些后端瓶頸(實際執行這些指令)。亂序 exec 通常可以很好地讓 CPU 運行得與最慢的瓶頸一樣快,而不是等到快取未命中加載之后才能獲取和解碼以后的指令。(請參閱,尤其是現代微處理器 90 分鐘指南!。)

在某些情況下,它可以在微碼更新禁用回圈緩沖區 (LSD) 的 Skylake CPU 上有所幫助,因此跨 32 位元組邊界拆分的微小回圈體最多可以每 2 個周期運行 1 次迭代(從 2 個單獨的快取行)。或者再次在 Skylake 上,以這種方式調整代碼對齊可以幫助避免 JCC 勘誤(這可以使您的部分代碼從舊版解碼而不是 uop 快取運行),如果您無法通過-Wa,-mbranches-within-32B-boundaries讓匯編程式解決它。如何減輕英特爾 jcc 勘誤表對 gcc 的影響?)。這些問題特定于 Skylake 衍生的微架構,并在 Ice Lake 中得到修復。

當然,反優化除錯模式代碼非常臃腫,以至于即使是緊密回圈也不太可能少于 8 uop,因此 32 位元組邊界問題可能不會造成太大影響。但是,如果您設法通過register在本地變數上使用來避免存盤/重新加載延遲瓶頸(是的,這僅在除錯構建中起作用,否則毫無意義1),通過管道獲取所有這些低效指令的前端瓶頸很可能會受到影響在 Skylake CPU 上,如果由于回圈內部或回圈底部的條件分支結束而導致內部回圈最終超出 JCC 勘誤表。

無論如何,正如 Eric 評論的那樣,您的任務可能更多是關于資料訪問模式,可能還有 layout 和 alignment大概涉及在一些大量記憶體上的小回圈,因為 L2 或 L3 快取未命中是唯一比禁用優化構建時慢到足以成為瓶頸的事情。在某些情況下可能是 L1d,如果您設法讓編譯器為除錯模式生成非可怕的 asm,或者如果負載使用延遲(不僅僅是吞吐量)是關鍵路徑的一部分。

腳注2:-O0很愚蠢,但register int i可以提供幫助

請參閱 C 回圈優化幫助以了解最終分配(禁用編譯器優化)回復:為除錯模式優化源代碼是多么愚蠢,或者為正常用例以這種方式進行基準測驗。但也提到了一些在這種情況下更快的事情(與正常構建不同),例如在單個陳述句或運算式中執行更多操作,因為編譯器不會跨陳述句將內容保存在暫存器中。

(另請參閱為什么 clang 會使用 -O0 產生低效的 asm(對于這個簡單的浮點求和)?有關詳細資訊)

register變數除外;那個過時的關鍵字仍然可以為使用 GCC 的未優化構建做一些事情(但不是 clang)。在最近的 C 版本中,它已被正式棄用甚至洗掉,但目前還沒有 C。

您肯定希望使用register int i讓除錯版本將其保存在暫存器中,并像手寫 asm 一樣撰寫您的 C。例如,arr[i]在適當的地方使用指標增量代替,尤其是對于沒有索引尋址模式的 ISA。

register變數在你的內部回圈中是最重要的,并且在禁用優化的情況下,編譯器可能不太聰明地決定哪個registervar 在用完時實際獲取暫存器。(x86-64 除了堆疊指標之外還有 15 個整數 reg,除錯版本會將其中一個用于幀指標。)

尤其是對于在回圈內發生變化的變數,以避免存盤/重新加載延遲瓶頸,例如for(register int i=1000000 ; --i ; );每個時鐘可能運行 1 次迭代,而register在 Skylake 等現代 x86-64 CPU 上不運行 5 或 6 次。

如果使用整數變數作為陣列索引,請將其設為intptr_tuintptr_t( #include <stdint.h>)(如果可能),因此編譯器不必將符號擴展從 32 位int重做為 64 位指標寬度以用于尋址模式。

(除非您正在為 AArch64 進行編譯,它具有采用 64 位暫存器和 32 位暫存器的尋址模式,進行符號或零擴展并忽略窄整數 reg 中的高垃圾。正是因為這是編譯器可以做到的。 t 總是優化掉。雖然它們通常可以歸功于有符號整數溢位是未定義的行為,允許編譯器擴大整數回圈變數或轉換為指標增量。)

也松散相關:為英特爾 Sandybridge 系列 CPU 中的管道取消優化程式有一節是關于通過快取效果故意使事情變慢,所以反其道而行之。可能不是很適用,IDK你的問題是什么樣的。

轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/465499.html

標籤:C 缓存 优化 结盟 内联汇编

上一篇:BPF驗證器以“Permissiondenied(13)!”拒絕。使用bpf_trace_printk()時

下一篇:Spring檔案集成:使用FileWritingMessageHandler寫入檔案時出現錯誤FileSystemException

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【從零開始擼一個App】Dagger2

    Dagger2是一個IOC框架,一般用于Android平臺,第一次接觸的朋友,一定會被搞得暈頭轉向。它延續了Java平臺Spring框架代碼碎片化,注解滿天飛的傳統。嘗試將各處代碼片段串聯起來,理清思緒,真不是件容易的事。更不用說還有各版本細微的差別。 與Spring不同的是,Spring是通過反射 ......

    uj5u.com 2020-09-10 06:57:59 more
  • Flutter Weekly Issue 66

    新聞 Flutter 季度調研結果分享 教程 Flutter+FaaS一體化任務編排的思考與設計 詳解Dart中如何通過注解生成代碼 GitHub 用對了嗎?Flutter 團隊分享如何管理大型開源專案 插件 flutter-bubble-tab-indicator A Flutter librar ......

    uj5u.com 2020-09-10 06:58:52 more
  • Proguard 常用規則

    介紹 Proguard 入口,如何查看輸出,如何使用 keep 設定入口以及使用實體,如何配置壓縮,混淆,校驗等規則。

    ......

    uj5u.com 2020-09-10 06:59:00 more
  • Android 開發技術周報 Issue#292

    新聞 Android即將獲得類AirDrop功能:可向附近設備快速分享檔案 谷歌為安卓檔案管理應用引入可安全隱藏資料的Safe Folder功能 Android TV新主界面將顯示電影、電視節目和應用推薦內容 泄露的Android檔案暗示了傳說中的谷歌Pixel 5a與折疊屏新機 谷歌發布Andro ......

    uj5u.com 2020-09-10 07:00:37 more
  • AutoFitTextureView Error inflating class

    報錯: Binary XML file line #0: Binary XML file line #0: Error inflating class xxx.AutoFitTextureView 解決: <com.example.testy2.AutoFitTextureView android: ......

    uj5u.com 2020-09-10 07:00:41 more
  • 根據Uri,Cursor沒有獲取到對應的屬性

    Android: 背景:呼叫攝像頭,拍攝視頻,指定保存的地址,但是回傳的Cursor檔案,只有名稱和大小的屬性,沒有其他諸如時長,連ID屬性都沒有 使用 cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DURATIO ......

    uj5u.com 2020-09-10 07:00:44 more
  • Android連載29-持久化技術

    一、持久化技術 我們平時所使用的APP產生的資料,在記憶體中都是瞬時的,會隨著斷電、關機等丟失資料,因此android系統采用了持久化技術,用于存盤這些“瞬時”資料 持久化技術包括:檔案存盤、SharedPreference存盤以及資料庫存盤,還有更復雜的SD卡記憶體儲。 二、檔案存盤 最基本存盤方式, ......

    uj5u.com 2020-09-10 07:00:47 more
  • Android Camera2Video整合到自己專案里

    背景: Android專案里呼叫攝像頭拍攝視頻,原本使用的 MediaStore.ACTION_VIDEO_CAPTURE, 后來因專案需要,改成了camera2 1.Camera2Video 官方demo有點問題,下載后,不能直接整合到專案 問題1.多次拍攝視頻崩潰 問題2.雙擊record按鈕, ......

    uj5u.com 2020-09-10 07:00:50 more
  • Android 開發技術周報 Issue#293

    新聞 谷歌為Android TV開發者提供多種新功能 Android 11將自動填表功能整合到鍵盤輸入建議中 谷歌宣布Android Auto即將支持更多的導航和數字停車應用 谷歌Pixel 5只有XL版本 搭載驍龍765G且將比Pixel 4更便宜 [圖]Wear OS將迎來重磅更新:應用啟動時間 ......

    uj5u.com 2020-09-10 07:01:38 more
  • 海豚星空掃碼投屏 Android 接收端 SDK 集成 六步驟

    掃碼投屏,開放網路,獨占設備,不需要額外下載軟體,微信掃碼,發現設備。支持標準DLNA協議,支持倍速播放。視頻,音頻,圖片投屏。好點意思。還支持自定義基于 DLNA 擴展的操作動作。好像要收費,沒體驗。 這里簡單記錄一下集成程序。 一 跟目錄的build.gradle添加私有mevan倉庫 mave ......

    uj5u.com 2020-09-10 07:01:43 more
最新发布
  • 歡迎頁輪播影片

    如圖,引導開始,球從上落下,同時淡入文字,然后文字開始輪播,最后一頁時停止,點擊進入首頁。 在來看看效果圖。 重力球先不講,主要歡迎輪播簡單實作 首先新建一個類 TextTranslationXGuideView,用于影片展示 文本是類似的,最后會有個圖片箭頭影片,布局很簡單,就是一個 TextVi ......

    uj5u.com 2023-04-20 08:40:31 more
  • 【FAQ】關于華為推送服務因營銷訊息頻次管控導致服務通訊類訊息

    一. 問題描述 使用華為推送服務下發IM訊息時,下發訊息請求成功且code碼為80000000,但是手機總是收不到訊息; 在華為推送自助分析(Beta)平臺查看發現,訊息發送觸發了頻控。 二. 問題原因及背景 2023年1月05日起,華為推送服務對咨詢營銷類訊息做了單個設備每日推送數量上限管理,具體 ......

    uj5u.com 2023-04-20 08:40:11 more
  • 歡迎頁輪播影片

    如圖,引導開始,球從上落下,同時淡入文字,然后文字開始輪播,最后一頁時停止,點擊進入首頁。 在來看看效果圖。 重力球先不講,主要歡迎輪播簡單實作 首先新建一個類 TextTranslationXGuideView,用于影片展示 文本是類似的,最后會有個圖片箭頭影片,布局很簡單,就是一個 TextVi ......

    uj5u.com 2023-04-20 08:39:36 more
  • 【FAQ】關于華為推送服務因營銷訊息頻次管控導致服務通訊類訊息

    一. 問題描述 使用華為推送服務下發IM訊息時,下發訊息請求成功且code碼為80000000,但是手機總是收不到訊息; 在華為推送自助分析(Beta)平臺查看發現,訊息發送觸發了頻控。 二. 問題原因及背景 2023年1月05日起,華為推送服務對咨詢營銷類訊息做了單個設備每日推送數量上限管理,具體 ......

    uj5u.com 2023-04-20 08:39:13 more
  • iOS從UI記憶體地址到讀取成員變數(oc/swift)

    開發除錯時,我們發現bug時常首先是從UI顯示發現例外,下一步才會去定位UI相關連的資料的。XCode有給我們提供一系列debug工具,但是很多人可能還沒有形成一套穩定的除錯流程,因此本文嘗試解決這個問題,順便提出一個暴論:UI顯示例外問題只需要兩個步驟就能完成定位作業的80%: 定位例外 UI 組 ......

    uj5u.com 2023-04-19 09:16:23 more
  • FIDE重磅更新!性能飛躍!體驗有禮!

    FIDE 開發者工具重構升級啦!實作500%性能提升,誠邀體驗! 一直以來不少開發者朋友在社區反饋,在使用 FIDE 工具的程序中,時常會遇到諸如加載不及時、代碼預覽/渲染性能不如意的情況,十分影響開發體驗。 作為技術團隊,我們深知一件趁手的開發工具對開發者的重要性,因此,在2023年開年,FinC ......

    uj5u.com 2023-04-19 09:16:15 more
  • 游戲內嵌社區服務開放,助力開發者提升玩家互動與留存

    華為 HMS Core 游戲內嵌社區服務提供快速訪問華為游戲中心論壇能力,支持玩家直接在游戲內瀏覽帖子和交流互動,助力開發者擴展內容生產和觸達的場景。 一、為什么要游戲內嵌社區? 二、游戲內嵌社區的典型使用場景 1、游戲內打開論壇 您可以在游戲內繪制論壇入口,為玩家提供沉浸式發帖、瀏覽、點贊、回帖、 ......

    uj5u.com 2023-04-19 09:15:46 more
  • iOS從UI記憶體地址到讀取成員變數(oc/swift)

    開發除錯時,我們發現bug時常首先是從UI顯示發現例外,下一步才會去定位UI相關連的資料的。XCode有給我們提供一系列debug工具,但是很多人可能還沒有形成一套穩定的除錯流程,因此本文嘗試解決這個問題,順便提出一個暴論:UI顯示例外問題只需要兩個步驟就能完成定位作業的80%: 定位例外 UI 組 ......

    uj5u.com 2023-04-19 09:14:53 more
  • FIDE重磅更新!性能飛躍!體驗有禮!

    FIDE 開發者工具重構升級啦!實作500%性能提升,誠邀體驗! 一直以來不少開發者朋友在社區反饋,在使用 FIDE 工具的程序中,時常會遇到諸如加載不及時、代碼預覽/渲染性能不如意的情況,十分影響開發體驗。 作為技術團隊,我們深知一件趁手的開發工具對開發者的重要性,因此,在2023年開年,FinC ......

    uj5u.com 2023-04-19 09:14:08 more
  • 游戲內嵌社區服務開放,助力開發者提升玩家互動與留存

    華為 HMS Core 游戲內嵌社區服務提供快速訪問華為游戲中心論壇能力,支持玩家直接在游戲內瀏覽帖子和交流互動,助力開發者擴展內容生產和觸達的場景。 一、為什么要游戲內嵌社區? 二、游戲內嵌社區的典型使用場景 1、游戲內打開論壇 您可以在游戲內繪制論壇入口,為玩家提供沉浸式發帖、瀏覽、點贊、回帖、 ......

    uj5u.com 2023-04-19 09:08:34 more