(I << 3) + (i << 1) আই * 10 সরাসরি ব্যবহারের চেয়ে 10 দিয়ে গুণিত করা কি আসলেই দ্রুত হয়?
এটি আপনার মেশিনে থাকতে পারে এবং নাও থাকতে পারে - যদি আপনি যত্ন নেন তবে আপনার আসল-বিশ্বের ব্যবহার পরিমাপ করুন।
একটি কেস স্টাডি - 486 থেকে কোর i7 পর্যন্ত
বেঞ্চমার্কিং অর্থপূর্ণভাবে করা খুব কঠিন, তবে আমরা কয়েকটি তথ্য দেখতে পারি। থেকে http://www.penguin.cz/~literakl/intel/s.html#SAL এবং http://www.penguin.cz/~literakl/intel/i.html#IMUL আমরা এক্স 86 ঘড়ি চক্র একটি ধারণা পেতে পাটিগণিত শিফট এবং গুণনের জন্য প্রয়োজন। বলুন আমরা "486" (সর্বশেষতম তালিকাভুক্ত), 32 বিট রেজিস্টার এবং তাত্ক্ষণিকভাবে আঁকড়ে থাকি, আইএমএল 13-42 চক্র এবং আইডিআইভি 44 নেয় Each প্রতিটি এসএএল 2 নেয়, এবং 1 যোগ করে, তাই এমনকি যারা একসাথে পৃষ্ঠপোষকভাবে চেহারা পরিবর্তন করছেন তাদের কয়েকটির সাথেও একটি বিজয়ীর মত।
মূল i7 সহ আজকাল:
( http://software.intel.com/en-us/forums/showthread.php?t=61481 থেকে )
বিলম্বটি পূর্ণসংখ্যা সংযোজনের জন্য 1 টি চক্র এবং পূর্ণসংখ্যার গুণনের জন্য 3 টি চক্র । আপনি ল্যাটেন্সি এবং thoughput এর পরিশিষ্ট C "হল Intel 64 এবং IA-32 আর্কিটেকচারের অপ্টিমাইজেশান রেফারেন্স ম্যানুয়াল", যা অবস্থিত অনুসন্ধান করতে পারেন http://www.intel.com/products/processor/manuals/ ।
(কিছু ইনটেল ব্লার্ব থেকে)
এসএসই ব্যবহার করে, কোর আই 7 একযোগে সংযোজন এবং গুণাগুলির নির্দেশনা জারি করতে পারে, ফলস্বরূপ প্রতি ঘড়ির চক্রে 8 ভাসমান-পয়েন্ট অপারেশন (এফএলওপি) শীর্ষের হারের সৃষ্টি করে
এটি আপনাকে কতদূর এগিয়েছে তার একটি ধারণা দেয়। অপ্টিমাইজেশন ট্রিভিয়া - বিট শিফটিং বনামের মতো*
90 এর দশকেও গুরুত্ব সহকারে নেওয়া হয়েছিল এখন কেবল অপ্রচলিত। বিট-শিফটিংটি এখনও দ্রুত, তবে আপনি যখন নিজের সমস্ত শিফট করেন এবং ফলাফলগুলি ধীরে ধীরে ধীরে ধীরে যোগ করেন ততক্ষণে দু'বারের নন / বিদ্যুতের জন্য। তারপরে, আরও নির্দেশাবলীর অর্থ আরও ক্যাশে ত্রুটি, পাইপলাইনে আরও সম্ভাব্য সমস্যা, অস্থায়ী রেজিস্টারগুলির আরও বেশি ব্যবহারের অর্থ স্ট্যাক থেকে নিবন্ধের সামগ্রীগুলিকে আরও সঞ্চয় এবং পুনরুদ্ধার করা হতে পারে ... সমস্ত প্রভাবগুলি অবশ্যই স্পষ্টভাবে প্রমাণ করতে এটি খুব জটিল হয়ে যায় তবে তারা হ'ল প্রধানত নেতিবাচক।
উত্স কোড বনাম বাস্তবায়নে কার্যকারিতা
আরও সাধারণভাবে, আপনার প্রশ্নটিকে সি এবং সি ++ ট্যাগ করা হয়। তৃতীয় প্রজন্মের ভাষা হিসাবে, এগুলি নির্দিষ্টভাবে অন্তর্নিহিত সিপিইউ নির্দেশের সেটটির বিশদটি গোপন করার জন্য তৈরি করা হয়েছে। তাদের ভাষার মানগুলি পূরণ করার জন্য , অন্তর্নিহিত হার্ডওয়্যারটি না করলেও তাদের অবশ্যই গুণন এবং শিফটিং অপারেশনগুলি (এবং অনেকগুলি) সমর্থন করতে হবে । এই জাতীয় ক্ষেত্রে, তাদের অন্যান্য অনেক নির্দেশাবলী ব্যবহার করে প্রয়োজনীয় ফলাফল সংশ্লেষ করতে হবে ize একইভাবে, সিপিইউয়ের অভাব থাকলে এবং কোনও এফপিইউ না থাকলে তাদের অবশ্যই ভাসমান পয়েন্ট অপারেশনের জন্য সফ্টওয়্যার সহায়তা সরবরাহ করতে হবে। আধুনিক সিপিইউ সমস্ত সমর্থন করে*
এবং<<
, সুতরাং এটি অযৌক্তিক তাত্ত্বিক এবং historicalতিহাসিক মনে হতে পারে, তবে তাত্পর্যপূর্ণ বিষয়টি হ'ল বাস্তবায়ন বাছাই করার স্বাধীনতা উভয় পথে চলেছে: এমনকি সিপিইউতে এমন একটি নির্দেশ রয়েছে যা সাধারণ ক্ষেত্রে উত্স কোডে অনুরোধ করা অপারেশনটি প্রয়োগ করে, সংকলকটি বিনামূল্যে অন্য যেটিকে পছন্দ করে তা চয়ন করুন কারণ সংকলকটির যে নির্দিষ্ট ক্ষেত্রে এটির মুখোমুখি হয়েছিল তার পক্ষে এটি আরও ভাল ।
উদাহরণ (একটি অনুমানী সমাবেশের ভাষা সহ)
source literal approach optimised approach
#define N 0
int x; .word x xor registerA, registerA
x *= N; move x -> registerA
move x -> registerB
A = B * immediate(0)
store registerA -> x
...............do something more with x...............
এক্সক্লুসিভ বা ( xor
) এর মতো নির্দেশাবলীর উত্স কোডের সাথে কোনও সম্পর্ক নেই, তবে কোনও কিছু দিয়ে নিজের সাথে xor-ing করা সমস্ত বিট সাফ করে, তাই এটি 0 তে সেট করার জন্য ব্যবহার করা যেতে পারে Source উত্স কোড যা মেমরির ঠিকানাগুলি বোঝায় যে কোনও ব্যবহৃত হচ্ছে না।
এই ধরণের হ্যাকগুলি কম্পিউটারের চারপাশে দীর্ঘকাল ধরে ব্যবহৃত হয়েছিল। 3 জিএল-এর প্রথম দিনগুলিতে, বিকাশকারীকে দ্রুতগতিতে সুরক্ষিত করতে কম্পাইলার আউটপুটটিতে বিদ্যমান হার্ড-হ্যান্ড-অপটিমাইজিং অ্যাসেম্বলি-ভাষা দেবকে সন্তুষ্ট করতে হয়েছিল। সম্প্রদায় যে উত্পাদিত কোড ধীর ছিল না, আরও ভার্বোজ বা অন্যথায় খারাপ। সংকলকগণ দ্রুত প্রচুর অপটিমাইজেশন গ্রহণ করেছেন - এটি কোনও পৃথক সংসদীয় ভাষা প্রোগ্রামার হতে পারে এর চেয়ে এটির আরও ভাল কেন্দ্রীভূত ভাণ্ডারে পরিণত হয়েছে, যদিও সেখানে সর্বদা সম্ভাবনা থাকে যে তারা নির্দিষ্ট ক্ষেত্রে অপরিহার্য হওয়ার সম্ভাবনা দেখা দেয় এমন একটি নির্দিষ্ট অপটিমাইজেশন মিস করে - মানুষ কখনও কখনও পারে এটিকে বাদ দিন এবং আরও ভাল কিছু পেতে শুরু করুন যখন সংকলকরা ঠিক সেভাবেই করেন যতক্ষণ না কেউ তাদের মধ্যে সেই অভিজ্ঞতা ফিরিয়ে দেয় যতক্ষণ না।
সুতরাং, এমনকি যদি কিছু নির্দিষ্ট হার্ডওয়্যারে স্থানান্তর এবং যোগ করা আরও দ্রুত হয় তবে কম্পাইলার লেখক সম্ভবত এটি নিরাপদ এবং উপকারী উভয়ই ঠিক তখনই কাজ করতে পারেন।
Maintainability
যদি আপনার হার্ডওয়্যার পরিবর্তন হয় আপনি পুনরায় সংকলন করতে পারেন এবং এটি লক্ষ্য সিপিইউতে সন্ধান করবে এবং আরও একটি সেরা পছন্দ করবে, যেখানে আপনি কখনই আপনার "অপটিমাইজেশন" বা পুনরায় সংকলন করতে চান না বা সংকলনের পরিবেশগুলি যে গুণটি ব্যবহার করবে এবং কোনটি স্থানান্তরিত হবে তা তালিকাভুক্ত করতে চান না। ১০++ বছর আগে রচিত সমস্ত অ-পাওয়ার-টু বিট-শিফট "অপটিমাইজেশন "গুলির কথা চিন্তা করুন যা আধুনিক প্রসেসরের উপর চলতে চলতে যে কোডটি তারা করছে সেগুলি এখন কমিয়ে দিচ্ছে ...!
ধন্যবাদ, জিসিসির মতো ভাল সংকলক সাধারণত যখন কোনও অপ্টিমাইজেশন সক্ষম করে (যেমন ...main(...) { return (argc << 4) + (argc << 2) + argc; }
-> imull $21, 8(%ebp), %eax
) সক্ষম হয় তখন সরাসরি গুনের সাথে বিট শিফট এবং পাটিগণিতগুলির একটি সিরিজ প্রতিস্থাপন করতে পারে তাই কোডটি সংশোধন না করে পুনরায় সংকলন এমনকি সহায়তা করতে পারে, তবে এটির নিশ্চয়তা নেই।
অজানা বিটশিফিং কোডটি গুণমান বা বিভাগ বাস্তবায়নের ক্ষেত্রে আপনি যা অর্জন করার জন্য চেষ্টা করেছিলেন তার তুলনায় অনেক কম ভাব প্রকাশযোগ্য, সুতরাং অন্যান্য বিকাশকারীরা এতে বিভ্রান্ত হবেন এবং একটি বিভ্রান্ত প্রোগ্রামার সম্ভবত তাত্পর্য পুনরুদ্ধারের প্রচেষ্টাতে বাগ প্রবর্তন বা প্রয়োজনীয় কিছু অপসারণ করার সম্ভাবনা বেশি। যদি আপনি কেবল অ-স্পষ্টতই কাজ করেন যখন সেগুলি সত্যই কার্যকরভাবে উপকারী হয় এবং তারপরে সেগুলি ভালভাবে নথিভুক্ত করে (তবে যাইহোক স্বজ্ঞাত যে কোনও জিনিস নথিভুক্ত না করে), সবাই আনন্দিত হবে।
আংশিক সমাধান বনাম সাধারণ সমাধান
আপনি যেমন কিছু অতিরিক্ত জ্ঞান থাকে, তাহলে আপনার যে int
ইচ্ছা সত্যিই শুধুমাত্র সংরক্ষণকারী মান হতে x
, y
এবং z
তারপর, আপনি কিছু নির্দেশগুলি কাজ করতে সক্ষম সেই মানের জন্য কাজ এবং আপনি আপনার ফলাফলের চেয়ে কম্পাইলার এর নেই যখন আরো দ্রুত পেতে হতে পারে যে অন্তর্দৃষ্টি এবং একটি বাস্তবায়ন প্রয়োজন যা সমস্ত int
মানের জন্য কাজ করে । উদাহরণস্বরূপ, আপনার প্রশ্ন বিবেচনা করুন:
বিট অপারেটর ব্যবহার করে গুণ এবং বিভাগ অর্জন করা যায় ...
আপনি গুণের বর্ণনা দিচ্ছেন, তবে ভাগ কেটে যাবে?
int x;
x >> 1; // divide by 2?
সি ++ স্ট্যান্ডার্ড 5.8 অনুযায়ী:
-৩- E1 >> E2 এর মান হ'ল E1 ডান স্থানান্তরিত E2 বিট অবস্থান। যদি E1 এর স্বাক্ষরবিহীন প্রকার থাকে বা E1 এর একটি স্বাক্ষরিত প্রকার এবং একটি ননজিগেটভেট মান রয়েছে, ফলাফলের মানটি E1 এর ভাগফলের অবিচ্ছেদ্য অংশ যা পাওয়ার E2 তে উত্পন্ন 2 পরিমাণ দ্বারা বিভক্ত হয়। যদি E1 এর একটি স্বাক্ষরিত ধরণ এবং negativeণাত্মক মান থাকে তবে ফলাফল মান বাস্তবায়ন সংজ্ঞায়িত হয়।
সুতরাং, আপনার বিট শিফটের একটি বাস্তবায়ন সংজ্ঞায়িত ফলাফল রয়েছে যখন x
নেতিবাচক হয়: এটি বিভিন্ন মেশিনে একইভাবে কাজ করতে পারে না। তবে, /
অনেক বেশি অনুমানযোগ্যভাবে কাজ করে। (এটি উভয়ই পুরোপুরি সামঞ্জস্যপূর্ণ নাও হতে পারে, কারণ বিভিন্ন মেশিনে নেতিবাচক সংখ্যার বিভিন্ন উপস্থাপনা থাকতে পারে এবং তাই একই রকম সংখ্যক বিট উপস্থাপনাটি তৈরি করার পরেও বিভিন্ন রেঞ্জ থাকে))
আপনি বলতে পারেন "আমি যত্ন করি না ... int
এটি কর্মচারীর বয়স সংরক্ষণ করছে, এটি কখনও নেতিবাচক হতে পারে না"। যদি আপনার কাছে সেই ধরণের বিশেষ অন্তর্দৃষ্টি থাকে তবে হ্যাঁ - আপনার >>
নিরাপদ অপ্টিমাইজেশন সংকলক দ্বারা আপনার কোডটিতে স্পষ্টভাবে না করা পর্যন্ত পার হতে পারে। তবে, এটি ঝুঁকিপূর্ণ এবং খুব কমই দরকারী যেমন আপনার এই ধরণের অন্তর্দৃষ্টি হবে না এবং একই কোডে কাজ করা অন্যান্য প্রোগ্রামাররা জানতে পারবেন না যে আপনি নিজের ডেটার কিছু অস্বাভাবিক প্রত্যাশা নিয়ে বাজি রেখেছেন ' হ্যান্ডলিং করব ... আপনার "অপ্টিমাইজেশন" এর কারণে তাদের সম্পূর্ণরূপে নিরাপদ পরিবর্তন ব্যাকফায়ার হতে পারে।
এমন কোনও ধরণের ইনপুট রয়েছে যা এইভাবে গুণ বা ভাগ করা যায় না?
হ্যাঁ ... উপরে উল্লিখিত হিসাবে, নেতিবাচক সংখ্যার বাস্তবায়ন সংজ্ঞায়িত আচরণ থাকে যখন বিট-শিফটিং দ্বারা "বিভক্ত" হয়।