موضوع مقاله: مجموعه دستورالعملها فشرده | مخاطب: عمومی | لحن: دانشنامه‌ای | ساختار: عنوان، مقدمه، 3 بخش، جمع‌بندی | مقاله: | # مجموعه دستورالعملها فشرده | مقدمه: مجموعه‌دستورالعمل فشرده (یا به اختصار «دستورهای فشرده») به روشی در طراحی معماری مجموعه‌دستور یک ریزپردازنده گفته می‌شود که هدفش کوتاه‌تر کردن قالب دستورهاست تا کدِ برنامه فضای کمتری بگیرد. | ## بخش 1: مجموعه دستورالعملها فشرده | در عمل، در بسیاری از پردازنده‌ها دستورهای فشرده معمولاً ۱۶‌بیتی‌اند، در حالی که همان پردازنده به طور معمول دستورهای ۳۲‌بیتی را اجرا می‌کند. این مجموعهٔ ۱۶‌بیتی یک ISA جداگانه نیست؛ بلکه فقط بخشی از مجموعه‌دستور کاملِ ۳۲‌بیتی به شمار می‌آید. کوچک‌تر شدن دستورها البته با محدودیت‌هایی همراه است: معمولاً تعداد دستورهای قابل استفاده کمتر می‌شود، هر دستور اغلب به‌جای سه عملوند فقط دو عملوند دارد، و انتخاب ثبات‌های قابل دسترس هم محدودتر می‌شود. این ایده را هیتاچی در ابتدا برای بالا بردن چگالی کُد در طراحی پردازنده‌های RISC خانوادهٔ SuperH مطرح کرد؛ زمانی که در نسخهٔ SH-5 قرار بود دستورها از قالب ۱۶‌بیتی به ۳۲‌بیتی منتقل شوند. طراحی جدید دو مجموعه‌دستور داشت: یکی مجموعه‌دستور کاملِ ۳۲‌بیتی و دیگری یک مجموعهٔ کوچک‌ترِ ۱۶‌بیتی با نام SHcompact که باعث می‌شد برنامه‌ها با حافظهٔ کمتری اجرا شوند. امروز دیگر کمبود حافظه مثل گذشته مسئلهٔ اصلی نیست، اما مزیت مهمِ فعلی این روش این است که مراجعه به حافظهٔ اصلی را کمتر می‌کند و در نتیجه مصرف انرژی—به‌ویژه در دستگاه‌های همراه—کاهش پیدا می‌کند. از آن‌جا که پتنت‌های اولیه حالا منقضی شده‌اند، این مفهوم در طراحی‌های مدرنِ مختلفی به چشم می‌خورد؛ از جمله در RISC-V که از همان ابتدا با در نظر گرفتن امکان استفاده از دستورهای فشرده طراحی شده است. با رواج پردازنده‌های ۶۴بیتی، این اصطلاح کمتر از گذشته استفاده می‌شود: چون در این پردازنده‌ها معمولاً قالب دستورها همچنان ۳۲بیتی است و از نظر فنی می‌توان آن را نوعی ISA فشرده دانست، اما چون این طراحی‌ها غالباً نسخهٔ گسترش‌یافتهٔ همان ISAهای ۳۲بیتیِ قبلی در یک خانوادهٔ پردازشی هستند، عملاً «فشرده‌سازی» مستقلی در کار نیست. مفهوم ریزپردازنده‌ها دستورهایشان را به صورت یک رشته از بیت‌ها کُد می‌کنند؛ این رشته معمولاً به بخش‌های ۸‌بیتی (یعنی بایت) تقسیم می‌شود. پردازنده می‌تواند این عملوند را از جاهای مختلفی بردارد: ممکن است در حافظهٔ اصلی باشد، یا در ناحیهٔ ویژهٔ «صفحهٔ صفر» ذخیره شده باشد، یا حتی یک مقدار ثابتِ صریح مثل «۱۰» باشد. هر کدام از این حالت‌ها در 6502 با یک کُد دستور ۸‌بیتیِ جداگانه (opcode) نمایش داده می‌شد؛ مثلاً اگر بخواهیم مقدار ثابت ۱۰ را به انباره اضافه کنیم، این دستور در حافظه به صورت 69$ 0A$ ذخیره می‌شود که در آن 0A$ نمایش شانزدهیِ عدد ۱۰ است. حتی تا اواخر دههٔ ۱۹۷۰ هم که ریزپردازنده‌ها کم‌کم از قالب‌های ۸‌بیتی به ۱۶‌بیتی مهاجرت می‌کردند، دستورهای با طول متغیر همچنان رایج بودند؛ برای مثال Intel 8086 هنوز opcodeهای ۸‌بیتی داشت که بسته به شیوهٔ آدرس‌دهی می‌توانستند بدون بایت اضافه بیایند یا تا پنج بایت دیگر بعد از خودشان داشته باشند. با حرکت صنعت به سمت سیستم‌های ۳۲‌بیتی—به‌خصوص از وقتی که ایدهٔ RISC کم‌کم تبدیل به جریان اصلی طراحی پردازنده‌ها شد—دستورهای با طول متغیر آرام‌آرام کنار رفتند. | ## بخش 2: مجموعه دستورالعملها فشرده | برای نمونه، در معماری MIPS همهٔ دستورها دقیقاً یک مقدار ۳۲‌بیتی دارند: شش بیتِ بالایی نقش opcode را بازی می‌کند و ۲۶ بیت باقی‌مانده، بسته به نوع دستور، برای نمایش عملوندها و مجموعهٔ نسبتاً محدودِ حالت‌های آدرس‌دهی به کار می‌رود. ثابت‌طول کردن دستورها یکی از ایده‌های کلیدیِ پشتِ کاراییِ نسل‌های اولیهٔ RISC بود؛ چون در معماری‌های طول‌متغیر، خواندن یک دستور ممکن بود بین یک تا شش چرخهٔ حافظه زمان ببرد و لازم بود مدارها و ارتباطات کنترلیِ بیشتری وجود داشته باشد تا پردازنده قبل از آماده شدنِ همهٔ بایت‌های دستور، سراغ اجرای آن نرود. در طراحی‌های RISC معمولاً خواندن و رمزگشایی دستور در یک چرخه انجام می‌شود و همین موضوع کارِ رمزگشا را بسیار ساده‌تر می‌کند. صرفه‌جویی‌ای که از حذف آن مدارهای قفل و بست (interlock) به دست می‌آید، معمولاً صرف اضافه کردن منطق‌های مفیدتر یا افزایش تعداد ثبات‌ها می‌شود؛ چیزهایی که مستقیماً روی کارایی اثر می‌گذارند. تراکم کد نقطه‌ضعف رویکرد RISC این است که خیلی از دستورها واقعاً به چهار بایت فضا احتیاج ندارند. در پردازندهٔ 6502 که عملاً فقط یک ثبات محاسباتیِ اصلی یعنی A دارد، این دستور صرفاً با همان opcode هشت‌بیتیِ خودش ($06) نمایش داده می‌شود. در پردازنده‌هایی که ثبات‌های بیشتری دارند، معمولاً کافی است در کنار opcode، شمارهٔ ثبات هم مشخص شود که آن هم چیزی حدود ۴ یا ۵ بیت جا می‌گیرد. در معماری MIPS، برای مثال، این دستور فقط به یک opcode شش‌بیتی و یک شمارهٔ ثبات پنج‌بیتی نیاز دارد؛ یعنی در مجموع ۱۱ بیت اطلاعات. با این حال، مثل بیشتر طراحی‌های RISC، همین دستور هم همچنان یک کلمهٔ کاملِ ۳۲‌بیتی را اشغال می‌کند. چون این نوع دستورهای ساده در برنامه‌ها زیاد تکرار می‌شوند، برنامه‌های RISC معمولاً نسبت به برنامهٔ مشابه روی یک پردازنده با دستورهای طول‌متغیر، حافظهٔ بیشتری مصرف می‌کنند. در دههٔ ۱۹۸۰، وقتی مفهوم RISC تازه داشت شکل می‌گرفت، بزرگ‌تر شدن اندازهٔ برنامه‌ها یکی از شکایت‌های رایج بود. چون دستورها فضای بیشتری می‌گرفتند، سیستم مجبور بود زمان بیشتری را صرف خواندن دستورها از حافظه کند. اما بعد از انجام بنچمارک‌ها و آزمون‌های گسترده، مشخص شد که RISC تقریباً در همهٔ موارد سریع‌تر است و این استدلال کم‌کم کنار گذاشته شد. | ## بخش 3: مجموعه دستورالعملها فشرده | با این حال، هنوز موقعیت‌هایی وجود دارد که صرف‌نظر از کارایی، مصرف حافظه یک نگرانی جدی باقی می‌ماند؛ مخصوصاً در سیستم‌های کوچک و کاربردهای نهفته. حتی در اوایل دههٔ ۲۰۰۰ هم قیمت DRAM آن‌قدر بالا بود که دستگاه‌های حساس به هزینه معمولاً حافظهٔ محدودی داشتند. این مجموعه‌دستور در دنیای واقعی محدودیت‌هایی دارد؛ مثلاً فقط می‌تواند محاسبات دو‌عملوندی از شکلِ A = A + B را انجام دهد، در حالی که بیشتر پردازنده‌های هم‌دوره از قالب سه‌عملوندی مثل A = B + C استفاده می‌کردند. با حذف یک عملوند، چهار بیت از طول دستور کم می‌شود (چون ۱۶ ثبات وجود دارد و برای مشخص کردن هر ثبات ۴ بیت لازم است)، اما در عوض نوشتن کدهای محاسباتی تا حدی پیچیده‌تر می‌شود. این موضوع اجازه می‌دهد سیستم با سرعت بالاتری کار کند، هرچند بخشی از این سود ممکن است به خاطر نیاز به دستورهای بیشتر برای انجام کارهایی که در قالب سه‌عملوندی با یک دستور انجام می‌شوند، تا حدی خنثی شود. برای این‌که با طراحی‌های قبلی‌اش سازگار بماند و برنامه‌های قدیمی همچنان قابل اجرا باشند، یک مجموعه‌دستور دوم هم اضافه کرد که SHcompact نام داشت. در SHcompact، دستورهای اصلیِ ۱۶‌بیتی به‌صورت یک‌طرفه روی دستورهای ۳۲‌بیتیِ داخلی نگاشت می‌شدند؛ یعنی برخلاف پردازنده‌های قدیمیِ میکروکُددار، قرار نبود یک دستورِ فشرده به چند دستور تبدیل شود. پردازنده‌های ARM که در نامشان حرف T داشتند، علاوه بر مجموعه‌دستور اصلیِ ۳۲‌بیتی، این حالت فشرده را هم پشتیبانی می‌کردند و می‌شد در حین اجرا با دستور BX به‌صورت پویا بین حالت ۳۲‌بیتی و ۱۶‌بیتی جابه‌جا شد. این کار با محدود کردن ثبات‌های قابل دسترس به هشت تا ممکن شده، چون در این حالت برای انتخاب هر ثبات فقط ۳ بیت لازم است. به همین دلیل، در حالت ۱۶‌بیتی، ثبات‌های ۰ و ۱ به‌جای آن‌که به همان شماره‌ها در MIPS32 اشاره کنند، روی ثبات‌های ۱۶ و ۱۷ نگاشت می‌شوند. کاربردهای امروزی از حدود سال ۲۰۱۵ به بعد، بسیاری از پردازنده‌ها به سمت قالب‌های ۶۴‌بیتی رفتند. در اغلب این طراحی‌ها، قالب دستورها همچنان ۳۲‌بیتی باقی مانده است، اما ثبات‌های داخلی به اندازهٔ ۶۴ بیت گسترش پیدا کرده‌اند. با تعریف اولیه، می‌شود این دستورها را «فشرده» دانست، چون طولشان از اندازهٔ کلمهٔ داده کوچک‌تر است. | ## جمع‌بندی | با این حال، در این کاربرد معمولاً از اصطلاح «دستورالعمل فشرده» استفاده نمی‌شود؛ چون وقتی دربارهٔ دستورهای فشرده صحبت می‌شود، تقریباً همیشه منظور نسخه‌های ۱۶‌بیتیِ ISA است.