gcc - জিসিসি কেন আংশিক রেজিস্টার ব্যবহার করে না?




assembly x86 (2)

আংশিক রেজিস্টারগুলি অনেকগুলি x86 প্রসেসরের উপর পারফরম্যান্স পেনাল্টি লাগায় কারণ লিখিতভাবে তাদের পুরো অংশ থেকে আলাদা আলাদা শারীরিক রেজিস্টারে নামকরণ করা হয়। (রেজিস্ট্রারটির নাম পরিবর্তন করে নামকরণের বাইরে আরও কার্যকর করার জন্য, এই প্রশ্নোত্তরটি দেখুন)।

কিন্তু যখন কোনও নির্দেশিকা পুরো রেজিস্টারটি পড়ে, তখন সিপিইউকে এটি সনাক্ত করতে হবে যে এটির কোনও একক শারীরিক নিবন্ধে সঠিক স্থাপত্য নিবন্ধের মান উপলব্ধ নেই। (এটি ইস্যু / পুনর্নামকরণের পর্যায়ে ঘটে, সিপিইউ ইউওপকে আদেশের বাইরে যাওয়ার সময়সূচীটিতে প্রেরণের জন্য প্রস্তুত করে))

একে আংশিক রেজিস্টার স্টল বলা হয়। অ্যাগনার ফগের মাইক্রোআরকিটেকচার ম্যানুয়ালটি এটি বেশ ভালভাবে ব্যাখ্যা করেছে:

8.৮ আংশিক নিবন্ধের স্টল (পিপিআরও / পিআইআই / পিআইআইআই এবং পেন্টিয়াম এম প্রারম্ভিক)

আংশিক রেজিস্টার স্টল এমন একটি সমস্যা যা আমরা যখন 32-বিট নিবন্ধের অংশে লিখি এবং পরে পুরো রেজিস্টার বা এর বড় অংশ থেকে পড়ি occurs
উদাহরণ:

; Example 6.10a. Partial register stall
mov al, byte ptr [mem8]
mov ebx, eax ; Partial register stall

এটি 5 - 6 টি ঘড়ির বিলম্ব দেয় । কারণ হ'ল AH স্বাধীন করার জন্য একটি অস্থায়ী রেজিস্টার আ.লীগকে দেওয়া হয়েছে assigned AL কাছ থেকে বাকী EAX মানটির সাথে মানটি সংযুক্ত করার আগে AL কাছে লেখা অবসর না হওয়া পর্যন্ত এক্সিকিউশন ইউনিট অপেক্ষা করতে হবে।

বিভিন্ন সিপিইউতে আচরণ :

আংশিক-নিবন্ধভুক্ত নাম পরিবর্তন না করে লেখার জন্য ইনপুট নির্ভরতা একটি মিথ্যা নির্ভরতা যদি আপনি কখনই পূর্ণ নিবন্ধক না পড়েন। এটি নির্দেশ-স্তরের সমান্তরালতা সীমাবদ্ধ করে কারণ অন্য কোনও কিছুর জন্য 8 বা 16-বিট রেজিস্টার পুনরায় ব্যবহার করা আসলে সিপিইউর দৃষ্টিকোণ থেকে স্বতন্ত্র নয় (16-বিট কোড 32-বিট রেজিস্টারগুলিতে অ্যাক্সেস করতে পারে, তাই এটি উপরের অংশে সঠিক মান বজায় রাখতে হবে) অর্ধেক)। এবং এছাড়াও, এটি AL এবং এএইচকে স্বাধীন করে না। যখন ইন্টেল পি 6-পরিবার ডিজাইন করেছিল (1993 সালে প্রকাশিত পিপিও) তখনও 16-বিট কোডটি সাধারণ ছিল, সুতরাং বিদ্যমান মেশিন কোডটি দ্রুত চালানোর জন্য আংশিক-নিবন্ধভুক্ত নামকরণ একটি গুরুত্বপূর্ণ বৈশিষ্ট্য ছিল। (বাস্তবে, অনেক বাইনারি নতুন সিপিইউগুলির জন্য পুনরায় সংকলিত হয় না))

এজন্য সংকলকগণ বেশিরভাগ আংশিক রেজিস্টারগুলি এড়িয়ে যান। আংশিক-নিবন্ধভুক্ত মিথ্যা নির্ভরতা (এএমডি) বা স্টলগুলি (ইন্টেল পি 6-পরিবার) এড়াতে যখনই তারা পূর্ণ রেজিস্টারে শূন্য করতে বা সংক্ষিপ্ত মানগুলি সাইন-প্রসারিত করার জন্য movzx / movsx ব্যবহার করে। সুতরাং বেশিরভাগ আধুনিক মেশিন কোড আংশিক-নিবন্ধভুক্ত নামকরণের ফলে খুব বেশি সুবিধা পাবে না, এজন্য সাম্প্রতিক ইন্টেল সিপিইউগুলি তাদের আংশিক-নিবন্ধের নামকরণের যুক্তিটিকে সহজতর করছে।

@ বিঅনরপের উত্তর যেমন উল্লেখ করেছে , সংকলকগণ এখনও আংশিক নিবন্ধগুলি পড়েন , কারণ এটি কোনও সমস্যা নয়। (এএইচ / বিএইচ / সিএইচ / ডিএইচ পড়া হাসওয়েল / স্কাইলেকে আরও বিলম্বের অতিরিক্ত চক্র যোগ করতে পারে, তবে স্যান্ডিব্রিজ-পরিবারের সাম্প্রতিক সদস্যদের আংশিক নিবন্ধগুলি সম্পর্কে আগের লিঙ্কটি দেখুন))

আরও মনে রাখবেন যে write আর্গুমেন্টগুলি গ্রহণ করে যে কোনও x86-64 সাধারণত কনফিগার করা জিসিসির জন্য পুরো 32-বিট এবং -৪-বিট রেজিস্টারগুলির প্রয়োজন হয় যাতে এটি কেবল mov dl, 3 একত্রিত করা যায় না। আকারটি ডেটা ধরণের দ্বারা নির্ধারিত হয়, তথ্যের মান নয়।

অবশেষে, নির্দিষ্ট প্রসঙ্গে, সি এর সচেতন হওয়ার জন্য ডিফল্ট যুক্তি প্রচার রয়েছে, যদিও এটি কেস নয়
প্রকৃতপক্ষে, RossRidge নির্দেশ করেছেন, কলটি সম্ভবত কোনও দৃশ্যমান প্রোটোটাইপ ছাড়াই করা হয়েছিল।

আপনার জীবাণু বিভ্রান্তিকর, যেমনটি @ জাস্টার দেখিয়েছে।
উদাহরণস্বরূপ mov rdx, 3 আসলে mov edx, 3 , যদিও উভয়েরই একই প্রভাব রয়েছে — অর্থাৎ পুরো rdx 3 স্থাপন করা।
এটি সত্য কারণ অবিলম্বে 3 MOV r32, imm32 জন্য সাইন-এক্সটেনশন এবং একটি MOV r32, imm32 32-র প্রয়োজন হয় না MOV r32, imm32 32 MOV r32, imm32 উপরের 32 বিট সাফ করে।

লিনাক্সের write(1,"hi",3) gcc -s -nostdlib -nostartfiles -O3 সাথে নির্মিত gcc -s -nostdlib -nostartfiles -O3 ফলাফল:

ba03000000     mov edx, 3 ; thanks for the correction jester!
bf01000000     mov edi, 1
31c0           xor eax, eax
e9d8ffffff     jmp loc.imp.write

আমি সংকলক বিকাশের মধ্যে নেই তবে যেহেতু এই রেজিস্টারে স্থানান্তরিত প্রতিটি মান ধ্রুবক এবং পরিচিত সংকলন-সময়, আমি আগ্রহী যে কেন dil পরিবর্তে dl , dil এবং al ব্যবহার করে না। কেউ কেউ যুক্তিযুক্ত হতে পারে যে এই বৈশিষ্ট্যটি পারফরম্যান্সে কোনও পার্থক্য তৈরি করবে না তবে mov $1, %rax => b801000000 এবং mov $1, %rax => b801000000 mov $1, %al => b001 মধ্যে mov $1, %rax => b801000000 আকারের মধ্যে একটি বড় পার্থক্য রয়েছে যখন আমরা mov $1, %al => b001 হাজার নিবন্ধকের প্রবেশাধিকারের কথা বলছি একটি কার্যক্রম. কোনও সফ্টওয়্যার এর কমনীয়তার অংশ না হলে কেবল ছোট আকারই নয়, এর কার্যকারিতাতেও এর প্রভাব পড়ে।

"জিসিসি কেন সিদ্ধান্ত নিয়েছে" যে কোনও ব্যাপার না তা কেউ ব্যাখ্যা করতে পারেন?


আসল আইবিএম পিসির মতো কিছুতে, যদি এইএইচ 0 টি ধারণ করে পরিচিত ছিল এবং 0x34 এর মতো মান সহ AX লোড করা দরকার ছিল, "MOV AL, 34h" ব্যবহার করে সাধারণত "MOV AX এর জন্য প্রয়োজনীয় 12 টির পরিবর্তে 8 টি চক্র নেওয়া হত, 0034h "- একটি দুর্দান্ত গতির উন্নতি (কোনও দিকনির্দেশ প্রাক-আনয়ন করা হলে 2 চক্রের মধ্যে কার্যকর করা যেতে পারে তবে অনুশীলনে 8088 তার বেশিরভাগ সময় ব্যয় প্রতি চার চক্র ব্যয়ে নির্দেশিকা আনার জন্য অপেক্ষা করে)। আজকের সাধারণ-উদ্দেশ্যে কম্পিউটারগুলিতে ব্যবহৃত প্রসেসরগুলিতে, তবে কোড আনার জন্য প্রয়োজনীয় সময়টি সাধারণত সামগ্রিক প্রয়োগের গতির জন্য একটি তাত্পর্যপূর্ণ বিষয় নয় এবং কোডের আকার সাধারণত কোনও বিশেষ উদ্বেগ নয়।

তদুপরি, প্রসেসর বিক্রেতারা যে ধরণের কোড লোক চালিত হতে পারে তার কার্যকারিতা সর্বাধিকতর করার চেষ্টা করে এবং আজকাল 32-বিট লোড নির্দেশাবলী হিসাবে 8-বিট লোড নির্দেশাবলী প্রায়শই প্রায় ব্যবহৃত হতে পারে না। প্রসেসরের কোরে প্রায়শই একযোগে একাধিক 32-বিট বা -৪-বিট নির্দেশাবলী কার্যকর করতে যুক্তি অন্তর্ভুক্ত থাকে তবে অন্য কোনও কিছুর সাথে একই সাথে 8-বিট অপারেশন চালানোর জন্য যুক্তি অন্তর্ভুক্ত করা যায় না। ফলস্বরূপ, যখন 8088-তে 8-বিট অপারেশনগুলি ব্যবহার করা সম্ভব হয়েছিল তখন 8088-তে একটি কার্যকর অপ্টিমাইজেশন ছিল, এটি নতুন প্রসেসরের ক্ষেত্রে এটি একটি গুরুত্বপূর্ণ পারফরম্যান্স ড্রেন হতে পারে।







x86-64