একটি অনুকূলিত ftol
ফাংশন লেখার সময় আমি কিছু খুব বিজোড় আচরণ পেয়েছিGCC 4.6.1
। আমাকে আপনাকে প্রথমে কোডটি দেখান (স্পষ্টতার জন্য আমি পার্থক্য চিহ্নিত করেছি):
দ্রুত_আরঙ্ক_আপনি, সি:
int fast_trunc_one(int i) {
int mantissa, exponent, sign, r;
mantissa = (i & 0x07fffff) | 0x800000;
exponent = 150 - ((i >> 23) & 0xff);
sign = i & 0x80000000;
if (exponent < 0) {
r = mantissa << -exponent; /* diff */
} else {
r = mantissa >> exponent; /* diff */
}
return (r ^ -sign) + sign; /* diff */
}
দ্রুত_আরঙ্ক_দুই, সি:
int fast_trunc_two(int i) {
int mantissa, exponent, sign, r;
mantissa = (i & 0x07fffff) | 0x800000;
exponent = 150 - ((i >> 23) & 0xff);
sign = i & 0x80000000;
if (exponent < 0) {
r = (mantissa << -exponent) ^ -sign; /* diff */
} else {
r = (mantissa >> exponent) ^ -sign; /* diff */
}
return r + sign; /* diff */
}
একই অধিকার মনে হচ্ছে? আচ্ছা জিসিসির দ্বিমত রয়েছে। সংকলনের পরেgcc -O3 -S -Wall -o test.s test.c
অ্যাসেম্বলি আউটপুট:
দ্রুত_আরঙ্কিত_আর, উত্পন্ন:
_fast_trunc_one:
LFB0:
.cfi_startproc
movl 4(%esp), %eax
movl $150, %ecx
movl %eax, %edx
andl $8388607, %edx
sarl $23, %eax
orl $8388608, %edx
andl $255, %eax
subl %eax, %ecx
movl %edx, %eax
sarl %cl, %eax
testl %ecx, %ecx
js L5
rep
ret
.p2align 4,,7
L5:
negl %ecx
movl %edx, %eax
sall %cl, %eax
ret
.cfi_endproc
দ্রুত_আরঙ্ক_দুই, উত্পন্ন:
_fast_trunc_two:
LFB1:
.cfi_startproc
pushl %ebx
.cfi_def_cfa_offset 8
.cfi_offset 3, -8
movl 8(%esp), %eax
movl $150, %ecx
movl %eax, %ebx
movl %eax, %edx
sarl $23, %ebx
andl $8388607, %edx
andl $255, %ebx
orl $8388608, %edx
andl $-2147483648, %eax
subl %ebx, %ecx
js L9
sarl %cl, %edx
movl %eax, %ecx
negl %ecx
xorl %ecx, %edx
addl %edx, %eax
popl %ebx
.cfi_remember_state
.cfi_def_cfa_offset 4
.cfi_restore 3
ret
.p2align 4,,7
L9:
.cfi_restore_state
negl %ecx
sall %cl, %edx
movl %eax, %ecx
negl %ecx
xorl %ecx, %edx
addl %edx, %eax
popl %ebx
.cfi_restore 3
.cfi_def_cfa_offset 4
ret
.cfi_endproc
এটি একটি চূড়ান্ত পার্থক্য। এটি আসলে খুব প্রোফাইলে প্রদর্শিত হয়, fast_trunc_one
% প্রায় 30 চেয়ে দ্রুত fast_trunc_two
। এখন আমার প্রশ্ন: এর কারণ কী?
-S -O3 -da -fdump-tree-all
। এটি মধ্যবর্তী প্রতিনিধিত্বের অনেক স্ন্যাপশট তৈরি করবে। পাশাপাশি তাদের (তারা সংখ্যাযুক্ত) পাশাপাশি চলুন এবং আপনি প্রথম ক্ষেত্রে অনুপস্থিত অপ্টিমাইজেশন খুঁজে পেতে সক্ষম হবেন।
int
করুন unsigned int
এবং দেখুন পার্থক্যটি অদৃশ্য হয়ে যায় কিনা।
(r + shifted) ^ sign
নয় r + (shifted ^ sign)
। আমার ধারণা এটি অপ্টিমাইজারকে বিভ্রান্ত করছে? এফডব্লিউআইডাব্লিউ, এমএসভিসি 2010 (16.00.40219.01) এমন তালিকা তৈরি করে যা একে অপরের সাথে প্রায় সমান: gist.github.com/2430454