व्यवहार में, कोई अतिरिक्त उपरि नहीं लगाया जाएगा । C ++ में, छोटे कार्यों को आमतौर पर कंपाइलर द्वारा ऑप्टिमाइज़ेशन के रूप में इनबिल्ट किया जाता है, इसलिए परिणामस्वरूप असेंबली में सभी ऑपरेशंस कॉलिसाइट पर होंगे- फ़ंक्शन एक दूसरे को कॉल नहीं करेंगे, क्योंकि फ़ंक्शंस अंतिम कोड में मौजूद नहीं होंगे, केवल गणितीय कार्य।
संकलक के आधार पर, आप इनमें से किसी एक फ़ंक्शन को दूसरे को कम या कम अनुकूलन (जैसा कि डीबग बिल्ड के साथ) कहते हैं। हालांकि उच्च अनुकूलन स्तर पर (रिलीज़ बिल्ड), उन्हें केवल गणित के लिए अनुकूलित किया जाएगा।
यदि आप अभी भी इसके बारे में पांडित्यपूर्ण होना चाहते हैं (जैसे कि आप एक पुस्तकालय बना रहे हैं), inline
कीवर्ड को operator*()
(और इसी तरह के आवरण कार्यों को) जोड़ना आपके इनलाइन को इनलाइन प्रदर्शन करने के लिए संकेत दे सकता है, या संकलक-विशिष्ट झंडे / वाक्यविन्यास का उपयोग कर सकता है: -finline-small-functions
, -finline-functions
, -findirect-inlining
, __attribute__((always_inline))
(टिप्पणी में @Stephane Hockenhull के बारे में उपयोगी जानकारी के लिए क्रेडिट) । व्यक्तिगत रूप से, मैं यह अनुसरण करता हूं कि मैं जो फ्रेमवर्क / लिबास का उपयोग कर रहा हूं, यदि मैं GLKit की गणित लाइब्रेरी का उपयोग कर रहा हूं, तो मैं केवल उस GLK_INLINE
मैक्रो का उपयोग करूंगा जो यह भी प्रदान करता है।
क्लैंग (Xcode 7.2 का Apple LLVM वर्जन 7.0.2 / clang-700.1.81) का उपयोग करके डबल-चेकिंग , निम्न main()
फ़ंक्शन (आपके कार्यों और एक भोले Vector3<T>
कार्यान्वयन के संयोजन में ):
int main(int argc, const char * argv[])
{
Vector3<int> a = { 1, 2, 3 };
Vector3<int> b;
scanf("%d", &b.x);
scanf("%d", &b.y);
scanf("%d", &b.z);
Vector3<int> c = a * b;
printf("%d, %d, %d\n", c.x, c.y, c.z);
return 0;
}
अनुकूलन ध्वज का उपयोग कर इस विधानसभा के लिए संकलित करता है -O0
:
.section __TEXT,__text,regular,pure_instructions
.globl _main
.align 4, 0x90
_main: ## @main
Lfunc_begin0:
.loc 6 30 0 ## main.cpp:30:0
.cfi_startproc
## BB#0:
pushq %rbp
Ltmp0:
.cfi_def_cfa_offset 16
Ltmp1:
.cfi_offset %rbp, -16
movq %rsp, %rbp
Ltmp2:
.cfi_def_cfa_register %rbp
subq $128, %rsp
leaq L_.str1(%rip), %rax
##DEBUG_VALUE: main:argc <- undef
##DEBUG_VALUE: main:argv <- undef
movl $0, -4(%rbp)
movl %edi, -8(%rbp)
movq %rsi, -16(%rbp)
.loc 6 31 15 prologue_end ## main.cpp:31:15
Ltmp3:
movl l__ZZ4mainE1a+8(%rip), %edi
movl %edi, -24(%rbp)
movq l__ZZ4mainE1a(%rip), %rsi
movq %rsi, -32(%rbp)
.loc 6 33 2 ## main.cpp:33:2
leaq L_.str(%rip), %rsi
xorl %edi, %edi
movb %dil, %cl
leaq -48(%rbp), %rdx
movq %rsi, %rdi
movq %rsi, -88(%rbp) ## 8-byte Spill
movq %rdx, %rsi
movq %rax, -96(%rbp) ## 8-byte Spill
movb %cl, %al
movb %cl, -97(%rbp) ## 1-byte Spill
movq %rdx, -112(%rbp) ## 8-byte Spill
callq _scanf
.loc 6 34 17 ## main.cpp:34:17
leaq -44(%rbp), %rsi
.loc 6 34 2 is_stmt 0 ## main.cpp:34:2
movq -88(%rbp), %rdi ## 8-byte Reload
movb -97(%rbp), %cl ## 1-byte Reload
movl %eax, -116(%rbp) ## 4-byte Spill
movb %cl, %al
callq _scanf
.loc 6 35 17 is_stmt 1 ## main.cpp:35:17
leaq -40(%rbp), %rsi
.loc 6 35 2 is_stmt 0 ## main.cpp:35:2
movq -88(%rbp), %rdi ## 8-byte Reload
movb -97(%rbp), %cl ## 1-byte Reload
movl %eax, -120(%rbp) ## 4-byte Spill
movb %cl, %al
callq _scanf
leaq -32(%rbp), %rdi
.loc 6 37 21 is_stmt 1 ## main.cpp:37:21
movq -112(%rbp), %rsi ## 8-byte Reload
movl %eax, -124(%rbp) ## 4-byte Spill
callq __ZmlIiiE7Vector3IDTmldtfp_1xdtfp0_1xEERKS0_IT_ERKS0_IT0_E
movl %edx, -72(%rbp)
movq %rax, -80(%rbp)
movq -80(%rbp), %rax
movq %rax, -64(%rbp)
movl -72(%rbp), %edx
movl %edx, -56(%rbp)
.loc 6 39 27 ## main.cpp:39:27
movl -64(%rbp), %esi
.loc 6 39 32 is_stmt 0 ## main.cpp:39:32
movl -60(%rbp), %edx
.loc 6 39 37 ## main.cpp:39:37
movl -56(%rbp), %ecx
.loc 6 39 2 ## main.cpp:39:2
movq -96(%rbp), %rdi ## 8-byte Reload
movb $0, %al
callq _printf
xorl %ecx, %ecx
.loc 6 41 5 is_stmt 1 ## main.cpp:41:5
movl %eax, -128(%rbp) ## 4-byte Spill
movl %ecx, %eax
addq $128, %rsp
popq %rbp
retq
Ltmp4:
Lfunc_end0:
.cfi_endproc
उपरोक्त में, __ZmlIiiE7Vector3IDTmldtfp_1xdtfp0_1xEERKS0_IT_ERKS0_IT0_E
आपका operator*()
फ़ंक्शन है और callq
किसी अन्य __…Vector3…
फ़ंक्शन को समाप्त करता है। यह विधानसभा के लिए काफी मात्रा में है। के साथ संकलन -O1
लगभग समान है, फिर भी __…Vector3…
कार्यों के लिए कॉल करना।
हालांकि, जब हम इसे करने के लिए टक्कर -O2
, callq
करने के लिए है __…Vector3…
गायब हो जाते हैं, एक साथ बदल दिया imull
अनुदेश ( * a.z
≈ * 3
), एक addl
अनुदेश ( * a.y
≈ * 2
), और बस का उपयोग कर b.x
मूल्य सीधे-अप (क्योंकि * a.x
≈ * 1
)।
.section __TEXT,__text,regular,pure_instructions
.globl _main
.align 4, 0x90
_main: ## @main
Lfunc_begin0:
.loc 6 30 0 ## main.cpp:30:0
.cfi_startproc
## BB#0:
pushq %rbp
Ltmp0:
.cfi_def_cfa_offset 16
Ltmp1:
.cfi_offset %rbp, -16
movq %rsp, %rbp
Ltmp2:
.cfi_def_cfa_register %rbp
.loc 6 33 2 prologue_end ## main.cpp:33:2
Ltmp3:
pushq %rbx
subq $24, %rsp
Ltmp4:
.cfi_offset %rbx, -24
##DEBUG_VALUE: main:argc <- EDI
##DEBUG_VALUE: main:argv <- RSI
leaq L_.str(%rip), %rbx
leaq -24(%rbp), %rsi
Ltmp5:
##DEBUG_VALUE: operator*=<int, int>:rhs <- [RSI+0]
##DEBUG_VALUE: operator*<int, int>:rhs <- [RSI+0]
##DEBUG_VALUE: main:b <- [RSI+0]
xorl %eax, %eax
movq %rbx, %rdi
Ltmp6:
callq _scanf
.loc 6 34 17 ## main.cpp:34:17
leaq -20(%rbp), %rsi
Ltmp7:
xorl %eax, %eax
.loc 6 34 2 is_stmt 0 ## main.cpp:34:2
movq %rbx, %rdi
callq _scanf
.loc 6 35 17 is_stmt 1 ## main.cpp:35:17
leaq -16(%rbp), %rsi
xorl %eax, %eax
.loc 6 35 2 is_stmt 0 ## main.cpp:35:2
movq %rbx, %rdi
callq _scanf
.loc 6 22 18 is_stmt 1 ## main.cpp:22:18
Ltmp8:
movl -24(%rbp), %esi
.loc 6 23 18 ## main.cpp:23:18
movl -20(%rbp), %edx
.loc 6 23 11 is_stmt 0 ## main.cpp:23:11
addl %edx, %edx
.loc 6 24 11 is_stmt 1 ## main.cpp:24:11
imull $3, -16(%rbp), %ecx
Ltmp9:
##DEBUG_VALUE: main:c [bit_piece offset=64 size=32] <- ECX
.loc 6 39 2 ## main.cpp:39:2
leaq L_.str1(%rip), %rdi
xorl %eax, %eax
callq _printf
xorl %eax, %eax
.loc 6 41 5 ## main.cpp:41:5
addq $24, %rsp
popq %rbx
popq %rbp
retq
Ltmp10:
Lfunc_end0:
.cfi_endproc
इस कोड के लिए, विधानसभा में -O2
, -O3
, -Os
, और -Ofast
सब नज़र समान।