এখানে একটি অ্যালগরিদমের একটি দস্তাবেজের লিঙ্ক রয়েছে যা ভিজ্যুয়াল স্টুডিওতে আমি দেখতে পাই এমন মানগুলি এবং কোড তৈরি করে (বেশিরভাগ ক্ষেত্রে) এবং আমি ধরে নিয়েছি যে একটি ধ্রুবক পূর্ণসংখ্যার দ্বারা পরিবর্তনশীল পূর্ণসংখ্যকে ভাগ করার জন্য আমি এখনও জিসিসিতে ব্যবহার করি।
http://gmplib.org/~tege/divcnst-pldi94.pdf
নিবন্ধে, একটি ইউরুর সাথে এন বিটস রয়েছে, একটি ইউডওয়ার্ডে 2 এন বিট রয়েছে, এন = অংক = ডিভিডেন্ড, ডি = ডিনোমিনেটর = ডিভাইডার, initially প্রথমে সিল (লগ 2 (ডি)) সেট করা হয়, শিপ্রি প্রি-শিফ্ট হয় (গুণনের আগে ব্যবহৃত হয়) ) = ই = ডি-তে শূন্য বিটের পিছনে সংখ্যা, শপোস্টটি হ'ল পোস্ট-শিফট (বহুবৃত্তের পরে ব্যবহৃত হয়), যথার্থ নির্ভুলতা = এন - ই = এন - শিপ্রে। লক্ষ্যটি হ'ল প্রাক-শিফট, গুণ এবং পোস্ট-শিফ্ট ব্যবহার করে এন / ডি গণনা অনুকূলিতকরণ।
Figure.২ চিত্রে নীচে স্ক্রোল করুন, যা সংজ্ঞা দেয় যে কীভাবে একটি উচ্চারণ গুণক (সর্বোচ্চ আকার এন + 1 বিট) উত্পন্ন হয়, তবে প্রক্রিয়াটি স্পষ্টভাবে ব্যাখ্যা করে না। আমি এটি নীচে ব্যাখ্যা করব।
চিত্র ৪.২ এবং চিত্র show.২ দেখায় যে কীভাবে বেশিরভাগ বিভাজনকারীদের জন্য গুণককে একটি এন বিট বা কম গুণক হিসাবে কমাতে পারে। সমীকরণ 4.5 ব্যাখ্যা করে যে কীভাবে সূত্রটি 4.1 এবং 4.2 চিত্রের এন + 1 বিট গুণকগুলির সাথে ডিল করতে ব্যবহৃত হয়েছিল।
আধুনিক এক্স 86 এবং অন্যান্য প্রসেসরের ক্ষেত্রে, গুণমান সময় নির্ধারিত হয়, তাই প্রাক-শিফট এই প্রসেসরের উপর কোনও সহায়তা করে না, তবে এটি এখনও এন + 1 বিট থেকে এন বিটগুলিতে গুণককে হ্রাস করতে সহায়তা করে। আমি জানি না যে জিসিসি বা ভিজ্যুয়াল স্টুডিওগুলি X86 টার্গেটগুলির জন্য প্রি-শিফটটি সরিয়ে দিয়েছে।
চিত্র 6.2 এ ফিরে যাওয়া। হালকা এবং mhigh এর জন্য অঙ্ক (লভ্যাংশ) কেবলমাত্র একটি বাদ্য (ডিভাইডার)> 2 ^ (এন -1) (যখন ℓ == এন => মলো = 2 ^ (2 এন)) এর ক্ষেত্রে বড় হতে পারে এন / ডি এর জন্য অনুকূলিত প্রতিস্থাপন একটি তুলনা (যদি এন> = ডি, কিউ = 1, অন্য কিউ = 0) হয়, সুতরাং কোনও গুণক তৈরি হয় না। Mlow এবং mhigh এর প্রাথমিক মানগুলি N + 1 বিট হবে এবং প্রতিটি এন + 1 বিট মান (mlow বা mhigh) উত্পাদন করতে দুটি udword / uword বিভাজক ব্যবহার করা যেতে পারে। উদাহরণ হিসাবে 64 বিট মোডে এক্স 86 ব্যবহার করুন:
; upper 8 bytes of dividend = 2^(ℓ) = (upper part of 2^(N+ℓ))
; lower 8 bytes of dividend for mlow = 0
; lower 8 bytes of dividend for mhigh = 2^(N+ℓ-prec) = 2^(ℓ+shpre) = 2^(ℓ+e)
dividend dq 2 dup(?) ;16 byte dividend
divisor dq 1 dup(?) ; 8 byte divisor
; ...
mov rcx,divisor
mov rdx,0
mov rax,dividend+8 ;upper 8 bytes of dividend
div rcx ;after div, rax == 1
mov rax,dividend ;lower 8 bytes of dividend
div rcx
mov rdx,1 ;rdx:rax = N+1 bit value = 65 bit value
আপনি এটি জিসিসির সাথে পরীক্ষা করতে পারেন। কীভাবে j = i / 5 পরিচালনা করা হয় তা আপনি ইতিমধ্যে দেখেছেন। কীভাবে j = i / 7 পরিচালনা করা হয় তা দেখুন (যা এন + 1 বিট গুণক ক্ষেত্রে হওয়া উচিত)।
বেশিরভাগ বর্তমান প্রসেসরের উপর, গুণকের একটি নির্দিষ্ট সময় থাকে, তাই প্রাক-শিফ্টের প্রয়োজন হয় না। এক্স ৮ For-এর জন্য, শেষ ফলাফলটি বেশিরভাগ বিভাজনকারীদের জন্য একটি দুটি নির্দেশ ক্রম, এবং 7 টির মত বিভাজনকারীদের জন্য পাঁচটি নির্দেশের ক্রম (পিডিএফ ফাইলের 4.5 এবং চিত্র 4.2 সমীকরণে এন + 1 বিট গুণক অনুকরণ করার জন্য)। এক্স 86-64 কোড উদাহরণ:
; rax = dividend, rbx = 64 bit (or less) multiplier, rcx = post shift count
; two instruction sequence for most divisors:
mul rbx ;rdx = upper 64 bits of product
shr rdx,cl ;rdx = quotient
;
; five instruction sequence for divisors like 7
; to emulate 65 bit multiplier (rbx = lower 64 bits of multiplier)
mul rbx ;rdx = upper 64 bits of product
sub rbx,rdx ;rbx -= rdx
shr rbx,1 ;rbx >>= 1
add rdx,rbx ;rdx = upper 64 bits of corrected product
shr rdx,cl ;rdx = quotient
; ...