c++ - Integer class wrapper performance -
i looking remodel existing library fixed point numbers. library namespaced functions operating on 32-bit signed integers. turn around , create fixed point class wraps integer, don't want pay performance penalty associated classes fine-grained, performance issue use case.
since prospective class has such simple data requirements, , no resources, thought might possible make class "value oriented", leveraging non-modifying operations , passing instances value reasonable. simple class if implemented, not part of hierarchy.
i wondering if possible write integer wrapper class in such way no real performance penalty incurred compared using raw integers. confident case, don't know enough compilation process jump it.
i know it's said stl iterators compiled simple pointer operations, , similar integer operations.
the library updated c++11 part of project anyway, i'm hoping @ least constexpr , other new features rvalue references, can push performance of class near of pure integer operations.
additionally, recommendations benchmarking performance differences between 2 implementations appreciated.
what's amusing question it's compiler dependent. using clang/llvm:
#include <iostream> using namespace std; inline int foo(int a) { return << 1; } struct bar { int a; bar(int x) : a(x) {} bar baz() { return << 1; } }; void out(int x) __attribute__ ((noinline)); void out(int x) { cout << x; } void out(bar x) __attribute__ ((noinline)); void out(bar x) { cout << x.a; } void f1(int x) __attribute ((noinline)); void f1(int x) { out(foo(x)); } void f2(bar b) __attribute ((noinline)); void f2(bar b) { out(b.baz()); } int main(int argc, char** argv) { f1(argc); f2(argc); }
gives the following ir:
define void @_z3outi(i32 %x) uwtable noinline { %1 = tail call %"class.std::basic_ostream"* @_znsolsei(%"class.std::basic_ostream"* @_zst4cout, i32 %x) ret void } define void @_z3out3bar(i32 %x.coerce) uwtable noinline { %1 = tail call %"class.std::basic_ostream"* @_znsolsei(%"class.std::basic_ostream"* @_zst4cout, i32 %x.coerce) ret void } define void @_z2f1i(i32 %x) uwtable noinline { %1 = shl i32 %x, 1 tail call void @_z3outi(i32 %1) ret void } define void @_z2f23bar(i32 %b.coerce) uwtable noinline { %1 = shl i32 %b.coerce, 1 tail call void @_z3out3bar(i32 %1) ret void }
and unsurprisingly, generated assembly identical:
.globl _z2f1i .align 16, 0x90 .type _z2f1i,@function _z2f1i: # @_z2f1i .ltmp6: .cfi_startproc # bb#0: addl %edi, %edi jmp _z3outi # tailcall .ltmp7: .size _z2f1i, .ltmp7-_z2f1i .ltmp8: .cfi_endproc .leh_func_end2: .globl _z2f23bar .align 16, 0x90 .type _z2f23bar,@function _z2f23bar: # @_z2f23bar .ltmp9: .cfi_startproc # bb#0: addl %edi, %edi jmp _z3out3bar # tailcall .ltmp10: .size _z2f23bar, .ltmp10-_z2f23bar .ltmp11: .cfi_endproc .leh_func_end3:
normally, long methods on class inlined, this
parameter , references can omitted easily. don't quite see how gcc mess up.
Comments
Post a Comment