tqchen commented on PR #634:
URL: https://github.com/apache/tvm-ffi/pull/634#issuecomment-4744873263

   Side codegen probe for dynamic `RuntimeTypeIndex()` access.
   
   Probe:
   
   ```cpp
   struct DynProbeObj : public tvm::ffi::Object {
     static constexpr const char* _type_key = "probe.DynProbe";
     TVM_FFI_DECLARE_OBJECT_INFO_PREDEFINED_TYPE_KEY(DynProbeObj, 
tvm::ffi::Object);
   };
   
   extern "C" int32_t ReadDynTypeIndex() {
     return DynProbeObj::RuntimeTypeIndex();
   }
   ```
   
   Compiler: `c++ (Ubuntu 11.4.0-1ubuntu1~22.04.2) 11.4.0` with `-std=c++17 -O2 
-fPIC`.
   
   Hot accessor asm:
   
   ```diff
    ReadDynTypeIndex:
      endbr64
   -  push   r12
   -  push   rbp
   -  push   rbx
   -  sub    rsp,0x20
   -  mov    rbp,QWORD PTR [rip+0x0]
   -         R_X86_64_REX_GOTPCRELX _ZGVZN...E6tindex-0x4
   -  ... stack canary/type_key setup ...
   -  movzx  eax,BYTE PTR [rbp+0x0]
   -  test   al,al
   -  je     <guard_acquire_path>
   -  mov    rbx,QWORD PTR [rip+0x0]
   -         R_X86_64_REX_GOTPCRELX _ZZN...E6tindex-0x4
   -  mov    eax,DWORD PTR [rbx]
   -  ... restore/ret ...
   -
   -guard_acquire_path:
   -  call   __cxa_guard_acquire
   -  call   TVMFFITypeGetOrAllocIndex@PLT
   -  call   __cxa_guard_release
   +  mov    rax,QWORD PTR [rip+0x0]
   +         R_X86_64_REX_GOTPCRELX _ZN11DynProbeObj11_type_indexE-0x4
   +  mov    eax,DWORD PTR [rax]
   +  ret
   ```
   
   Symbol sizes from `nm -S --size-sort`:
   
   | Symbol | Before | After |
   |---|---:|---:|
   | `ReadDynTypeIndex` | 176 B | 14 B |
   | `ForceDynTypeIndexInit` | 176 B | 9 B |
   | `DynProbeObj::_GetOrAllocRuntimeTypeIndex` | inlined into callers | 179 B 
weak cold symbol |
   | `_GLOBAL__sub_I_probe.cc` | none | 21 B startup + 20 B cold |
   
   Section-size diff from `size -A probe.o`:
   
   | Section | Before | After | Delta |
   |---|---:|---:|---:|
   | `.text` | 352 B | 14 B | -338 B |
   | `.text.unlikely*` | 32 B | 208 B | +176 B |
   | `.text.startup` | 0 B | 21 B | +21 B |
   | `.init_array` | 0 B | 8 B | +8 B |
   | `_GetOrAllocRuntimeTypeIndex` local static guard | 8 B | 8 B | 0 B |
   | `_GetOrAllocRuntimeTypeIndex` local `tindex` | 4 B | 4 B | 0 B |
   | new inline `_type_index` guard | 0 B | 8 B | +8 B |
   | new inline `_type_index` storage | 0 B | 4 B | +4 B |
   | `.rodata*` type key | 15 B | 15 B | 0 B |
   | `.gcc_except_table*` | 36 B | 14 B | -22 B |
   | `.eh_frame` | 208 B | 184 B | -24 B |
   | total object | 769 B | 634 B | -135 B |
   
   Takeaway: the static inline cache adds a small guard/init/data cost, but 
removes the guarded allocation path from the hot accessor. The hot load becomes 
direct, `_GetOrAllocRuntimeTypeIndex` moves to cold/startup code, and this 
probe still shrinks overall object size.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to