آفت شبیه سازی x86
آدرس مقاله: https://fex-emu.com/Scourge-of-emulation/ آدرس نظرات: https://news.ycombinator.com/item?id=49750094 امتیاز: 246 # نظرات: 67
به اولین مقاله ویژه در سایت ما خوش آمدید. ما یک مشکل مداوم را با شبیه سازی x86 پوشش خواهیم داد که بر هر برنامه ای که شبیه سازی می کنیم تأثیر می گذارد. این به یک اصطلاح فراگیر منتهی می شود که پیامدهای گسترده ای دارد. شبیه سازی مدل حافظه سفارش کل فروشگاه x86 (x86-TSO).
مشکلات تقلید این مدل حافظه در مدل حافظه سفارشی ضعیفی که ARM تعریف می کند، چندوجهی است و مسائل متعددی را پوشش می دهد. ما در این مقاله قصد داریم تمام مشکلاتی که می توانیم با آنها روبرو شویم و راه هایی که حل می کنیم (یا در برخی موارد نمی توانیم حل کنیم) را مرور کنیم. برای خود یک میان وعده و یک نوشیدنی گرم تهیه کنید، این یک نوشیدنی طولانی خواهد بود.
قبل از بررسی نحوه حل مشکل مدل حافظه x86، ابتدا باید دقیقا در مورد چیستی آن صحبت کنیم. مدل حافظه مجموعه ای از قوانین برای نحوه رفتار دسترسی های حافظه در یک سیستم در رابطه با یکدیگر است. قوانین نحوه تعامل بارها و ذخیرهها در یک محیط تک رشتهای یا چند رشتهای را دیکته میکنند. تعداد انگشت شماری از مدلهای حافظه محبوب وجود دارد که در اشکال مختلف سختافزار پیادهسازی شدهاند، اما دو موردی که امروز به آن اهمیت میدهیم، مدل سازگاری آرام (یا ضعیف) ARM و نوع x86 مدل سازگاری Total-Store-Ordering است.
این دو مدل اساسا دو افراطی طیف هستند. جایی که ARM راحت ترین است و بهینه سازی سخت افزاری قابل توجهی را امکان پذیر می کند. و x86 سختگیرانهترین مدل است که یک مدل هماهنگی بسیار قوی را اعمال میکند که فضای زیادی برای بهینهسازی نمیدهد. یکی از مواردی که باید در مورد مدل های حافظه مراقب باشید، تفاوت بین ثبات و اتمی است. در حالی که اینها مرتبط هستند، اما در همه موارد یکسان نیستند و تضمین شده نیستند.
بهترین راه برای توضیح نحوه عملکرد تفاوتها در مدلهای حافظه این است که از نحوه مدیریت x86 شروع کنیم. با توجه به اینکه TSO در نحوه عملکرد آن بسیار سخت گیر است، برنامه نویس می تواند فرض کند که وقتی یک حافظه ذخیره می شود، این به طور منسجم برای تمام پردازنده های دیگر در سیستم قابل مشاهده است. این به علاوه به این معنی است که وقتی بارگذاری حافظه رخ میدهد، تمام ذخیرههای قبل از آن «بهطور منطقی» تکمیل شدهاند یا حداقل قابل مشاهده هستند. این با انتظارات برنامه نویس مطابقت دارد، شما در حافظه می نویسید، در هنگام نوشتن قابل مشاهده می شود، زیرا فکر کردن به آن هنگام برنامه نویسی بصری است.
فروشگاهها بهطور مؤثری میزان دید بارها را سفارش میدهند، بنابراین نام مدل را نامگذاری میکنند. کمی تفاوت های ظریف در نحوه عملکرد آن وجود دارد، اما درک آن کاملا ضروری نیست.
مدل حافظه ضعیفی که ARM دارد در مورد نحوه عملکرد آن کمی کمتر بصری است. بهطور پیشفرض، بارگیریهای حافظه معمولی و ذخیرههایی که ARM استفاده میکند، در بین پردازندههای سیستم شما کاملا منسجم نیستند و به CPU اجازه میدهند در بیشتر مواقع کارآمدتر کار کند. هنگامی که یک دستور ذخیره اجرا می شود، آن قسمت از حافظه (حافظه پنهان) بلافاصله برای سایر پردازنده های سیستم قابل مشاهده نیست. صرفه جویی در مصرف انرژی و کارایی گرانبها، زیرا از نظر سخت افزاری گران است تا خطوط حافظه پنهان هسته های دیگر را باطل کنند یا به آنها اجازه دهید تا حافظه پنهان پردازنده دیگری را زیر نظر بگیرند.
به همین ترتیب، اگر پردازنده ای داده ها را از حافظه ای که پردازنده دیگری روی آن نوشته است بارگیری کند، تضمین نمی شود که این بار حتی این حافظه به روز شده را ببیند. این به نظر می رسد که باعث ایجاد برخی مشکلات مهم در یک برنامه چند رشته ای می شود، درست است؟ نسخههای قدیمیتر ARM (ARMv7 و قدیمیتر) از یک دستورالعمل مانع حافظه برای اطمینان از سفارش استفاده میکردند که پیامدهای عملکرد قابل توجهی داشت.
برای دور زدن این محدودیت سازگاری، ARM دستورالعملهای حافظه بارگیری و ذخیرهسازی را نیز معرفی کرد. در زبان C++ این به ترتیب با تعریف std::atomic memory_order_acquire و memory_order_release نگاشت می شود. در اصطلاح ARM، این دستورالعمل ها نیز از نظر فنی به عنوان عملیات اتمی در نظر گرفته نمی شوند، اما برنامه نویسان این دو را با هم ترکیب می کنند. FEX از واژه های atomic-load و atomic-store به همین معنی استفاده کرده است! معمولا تمایز اهمیتی ندارد، اما هنگام بحث در مورد این موضوعات ممکن است بهتر باشد که در مورد آن متمایز باشید.
مورد استفاده اولیه برای این دستورالعمل ها، اجباری کردن مرتب سازی حافظه بین این دسته از دستورالعمل ها است. ARM این را مدل "رابطه سازگاری متوالی (RCsc)" می نامد. بدون پرداختن به علفهای هرز در مورد نحوه عملکرد این مدل، اصل اساسی این است که دستورالعملهای بارگیری باید بهطور متوالی و بدون ترتیبدهی مجدد رعایت شوند، و دستورالعملهای انتشار فروشگاه نیز باید در حین انجام معنایی «موانع سفارششده قبل» رعایت شوند. حذف دستورالعمل های پرهزینه مانع حافظه مورد نیاز در نسخه های قدیمی معماری ARM.
زمانی که در حال تقلید از مدل حافظه x86-TSO هستیم، در ARMv8.0-a از آنجا شروع می کنیم. ما کاری میکنیم که تمام بارهای حافظه x86 به دستورالعملهای بارگیری ARM و حافظههای x86 به دستورالعملهای ذخیرهسازی تبدیل شوند. این به FEX عملا همان معنای حافظه x86 را می دهد، اگرچه ما در واقع سختگیرتر از آنچه لازم است هستیم. این به این دلیل است که ما هیچ حد وسطی نداشتیم که دقیقا با رفتار مطابقت داشته باشد. همانطور که ممکن است تصور شود، تقلید از TSO با این دستورالعمل ها بسیار پرهزینه است و ما معیارهای کوچکی داریم که می تواند این را نشان دهد.
از آنجایی که پردازندههای ARM طوری طراحی نشده بودند که این دستورالعملهای نسبتا نادر کسب/انتشار را داشته باشند، به طور ناگهانی به اکثریت قریب به اتفاق دستورالعملهای اجرا شده تبدیل میشوند.
ابتدا بیایید با چیزی آسان شروع کنیم و از یک میکروبنچمارک استفاده کنیم که نسبت به سخت افزار نسبتا خوب است. بدون حاشیه های پیچیده، فقط دسترسی به حافظه در حالت معمولی. این به ما برخی از اعداد پایه را برای اینکه بهترین وضعیت باید چه باشد می دهد.
بیایید این نمودار را بشکنیم زیرا چند داستان جالب به ما می گوید. ستونهای Load and Store هر دستگاه نشاندهنده عدد عملکرد پایه ما است که سختافزار ما باید در تلاش برای رسیدن به آن باشد. اینها سعی نمی کنند پهنای باند حافظه هر سیستم را به حداکثر برسانند، اما برای هر نوع عملیات به همان میزان کار می کنند. اگر توجه خود را به نتایج بارگیری جمع آوریم معطوف کنیم، می بینیم که از پنج تست CPU، سه مورد از آنها با استفاده از بارهای کسب بار، عملکرد آنها تا حد زیادی با مشکل مواجه شده است!
علاوه بر این، میتوانیم ببینیم که CPU AmpereOne دارای دستورالعملهای ذخیرهسازی است که در مقایسه با نتایج دیگر بسیار پایین است، و دستورالعملهای بارگیری M1 Acquire/LRCPC نیز کمی پایینتر از خط پایه هستند.
نتایج AmpereOne به طور خاص نشان میدهد که این مسیر قدیمی چقدر میتواند بد شود. این دستورالعمل ها هرگز برای استفاده به این روش طراحی نشده اند. استفاده از معنای اکتسابی-انتشاری برای هر بار برای شبیهسازی x86، در واقع محدودیتهای واقعا سختی را بر CPUهای ARM تحمیل میکند، زیرا دستورالعملهای بارگذاری دیگر نمیتوانند در اطراف یکدیگر مرتب شوند. بنابراین وقتی میلیونها نفر از آنها در هر ثانیه پرواز دارند، واقعا انتظار نمیرود که عملکرد خوب باشد. اما از آنجایی که اینها تنها دستورالعمل هایی هستند که با ARMv8.0-a داشتیم، این همان چیزی است که باید استفاده می کردیم.
در حالی که Cortex-X4 و Cortex-X925 عملکرد شگفتانگیزی برای اینها دارند، میتوانید ببینید که چگونه Oryon-3 اهمیت آنها را بیاهمیت کرده است.
بیایید نگاهی دقیقتر به دستورالعملهای بارگذاری LRCPC بیندازیم، که از زمان ARMv8.3 اجباری است. این برنامه افزودنی مجموعه ای از دستورالعمل های بارگذاری جدید را به ARM ISA اضافه می کند و یک مدل حافظه جدید را در بالای مدل RCsc ARM از قبل اضافه می کند. این مدل حافظه جدید "Release Consistency پردازنده سازگار (RCpc)" همان چیزی است که ما میخواستیم! این برنامه افزودنی بر اساس الزاماتی طراحی شده است که شبیه سازی x86 به آن نیاز دارد و انتظار می رود که به شدت بر روی سخت افزاری که آن را پیاده سازی می کند استفاده شود.
همانطور که از نمودار می بینید، تقریبا همه پلتفرم ها دارای بارهای LRCPC خود هستند که با بارهای معمولی آنها در عملکرد مطابقت دارد.
با این افزونه جدید که توسط نسخه های جدیدتر ARM اجباری شده است، ما اساسا عملکرد حافظه حل شده را دریافت می کنیم. حداقل با توجه به این معیار خرد، به نظر می رسد که چنین باشد. هنگامی که FEX این افزونه را شناسایی کرد، استفاده از دستورالعملهای Acquire-Load را به طور کامل متوقف میکنیم و به جای آن به LRCPC-Load میرویم. اما با آن نتیجه Apple M1 چه اتفاقی میافتد؟
اینجاست که ما باید مسیر اپل را برای حل این مشکل تحسین کنیم. آنها با پردازنده های Apple Silicon خود مستقیما از مدل حافظه x86-TSO پشتیبانی می کنند. هنگامی که ویژگی CPU تغییر می کند، دستورالعمل های ARM بارگیری/ذخیره منظم آنها رفتار را تغییر می دهد تا مطابق با آنچه x86 نیاز دارد، مطابقت داشته باشد. آنها این مسیر را طی کردند و می دانستند که هنگام تغییر انحصاری به اکوسیستم ARM به یک راه حل با کارایی بالا برای سخت افزار خود نیاز دارند.
به همین دلیل است که در سختافزار آنها، دستورالعملهای بارگذاری LRCPC در واقع نام مستعار دستورالعملهای بارگیری آنها هستند، زیرا شبیهساز x86 آنها حتی از این دستورالعملها استفاده نمیکند! از آنجایی که آنها مدل حافظه x86 را پیادهسازی میکنند، فقط از دستورالعملهای بارگذاری/ذخیره منظم استفاده میکنند، که میتواند در نتایج میکروبنچ ما به عنوان سربار عملکرد غیرقابل تشخیص مشاهده شود. برای منصفانه بودن در مورد سایر پلتفرمها، این تغییر حالت TSO تا حدی تأثیر عملکردی دارد، ما فقط آن را در اینجا نمیبینیم.
هنگامی که FEX این ویژگی CPU را از Asahi Linux شناسایی میکند، این ویژگی را نیز فعال میکنیم و بهبود عملکرد «رایگان» را دریافت میکنیم. یک نگرانی بالقوه این است که هنگام پرش بین شبیه سازی x86 و کد ARM، کد ARM سربار غیرضروری را پرداخت می کند زیرا همه دسترسی های آن اکنون TSO هستند. در حالی که این یک نگرانی منطقی است، میزان اجرای کد بومی ARM تحت شبیه سازی به 0% نزدیک می شود. به عنوان یک توسعهدهنده، اهمیتی نمیدهید که 1% دسترسیها به حافظه 10% کندتر میشوند، برای شما مهم است که 99% دسترسیها به 15% "ایدهآل" تبدیل شوند (همانطور که در نتایج AmpereOne نشان داده شده است).
به عنوان یک نکته، ما فکر می کنیم حالت TSO بهترین مسیر برای اطمینان از شبیه سازی x86 با کارایی بالا در پلت فرم است. زیرا این تضمین می کند که هر دستورالعمل دسترسی به حافظه همانطور که ما می خواهیم یا انتظار داریم رفتار می کند. این با برنامه افزودنی رسمی FEAT_LRCPC نشان داده شده است که در واقع دارای سه نسخه است که هر بار بانداژ را برای پیاده سازی اعمال می کند.
حتی با این سه برنامه افزودنی، رفتار حاشیهای وجود دارد که نمیتوان آن را به خوبی شبیهسازی کرد که انگار یک کلید سختافزاری TSO داریم. ما انتظار داریم با گذشت زمان، نسخههای افزونههای دیگری نیز وجود داشته باشد، و سعی میکنیم برخی از مشکلات اضافی را که بعدا در مقاله مورد بحث قرار خواهیم داد، برطرف کنیم.
در بخش قبل، ما با سختافزار ARM خوب رفتار میکردیم و با الزامات همترازی سختافزار زیربنایی بازی میکردیم تا پایهای برای اینکه عملکرد باید چگونه باشد. اگرچه هنگام تقلید x86، ابتدا از همان ابتدا با یک مشکل فاحش مواجه می شویم. برنامه های x86 مورد علاقه شما به تراز اهمیتی نمی دهند! آنها هر طور که بخواهند به حافظه دسترسی خواهند داشت، از دانهبندیهای حافظه پنهان عبور میکنند، و اتمیهایی را انجام میدهند که تراز نیستند. شما به مشکلات تراز فکر می کنید، این بازی ها این کار را انجام می دهند.
این مشکل به قدری بد است که اصطلاحی با آن به نام split-locks داریم. اینها آنقدر بزرگ هستند که حتی هسته لینوکس هم وقتی این اتفاق میافتد میگیرد و وقتی بازیها را انجام میدهند، سرعت بازیها را کاهش میدهد! باعث می شود بسیاری از گیمرها با گزینه های هسته سرهم بندی کنند تا از کاهش سرعت جلوگیری کنند!
اما ما هنوز در مورد قفلهای تقسیمبندی کامل صحبت نمیکنیم، اجازه دهید فقط با دستورالعملهای ذخیرهسازی بار در محیطی که به تراز کردن اهمیتی نمیدهد شروع کنیم. x86 تضمین های خاصی را به برنامه نویس می دهد. اگر Load-Store را انجام دهید و آن را در داخل یک حافظه پنهان قرار دهید، آن load-store هم اتمی خواهد بود و هم همچنان با مدل انسجام همانطور که قبلا توضیح داده شد مطابقت دارد. با این حال، برای اینکه کمی با توسعهدهندگان سختافزار خوب رفتار کنیم، اگر load-store از خط کش عبور کند، دادهها اتمی نیستند و سایر رشتهها میتوانند آن را پاره کنند و خواهند دید.
بنابراین برنامه نویس باید مراقب باشد زیرا یک load-store پایه یک قفل تقسیم نیست.
مشکل شبیهسازی این دسترسیهای اولیه با load-acquire/store-release این است که ARMv8.0 به چیزی نیاز دارد که به عنوان تراز طبیعی شناخته میشود. این بدان معناست که برای هر اندازه داده ای که به آن دسترسی پیدا می شود، افست در حافظه باید با اندازه آن مطابقت داشته باشد. بنابراین برای دسترسی 8 بایتی، باید در افست باشد. 0، 8، 16، 24، و غیره. این برای برنامه های بومی ARM به خوبی کار می کند، اما وقتی از الزامات تراز طبیعی پیروی نکنیم چه اتفاقی می افتد؟ برای ARM، این به معنای دستورالعمل با خطای تراز کردن است.
سخت افزار تأیید می کند که الزامات تراز برآورده شده است و اگر آنها نباشند، CPU دچار مشکل می شود. این معمولا منجر به تصادف می شود اما FEX هندلینگ خاصی را انجام می دهد.
در داخل مکانیسم JIT FEX، ما دستورالعملهای ذخیره بار حافظه را که ذخیرههای بارگذاری x86 را شبیهسازی میکنند، پیگیری میکنیم. وقتی می دانیم که یک load-store می تواند یک خطای هم ترازی ایجاد کند، چیزی را داریم که به عنوان Patchpoint در کد شناخته می شود. برای دستورالعمل های load-store، این به عنوان یک دستورالعمل NOP قبل یا بعد از load-store نشان داده می شود. هنگامی که یک خطای تراز به عنوان یکی از این نقاط وصله رخ می دهد، FEX خطا را ضبط می کند، کد را از یک دستورالعمل load-acquire/store-release به یک load-store معادل اولیه وصله می کند و دستورالعمل را در یک مانع حافظه داده می پیچد. سپس به اجرا ادامه می دهد!
کل بحث قبلی در مورد اینکه چگونه ARMv8.0-a این دستورالعملهای جدید فانتزی بارگیری و ذخیرهسازی را اضافه کرد؟ در عوض زمانی که رفتار تراز با هم مطابقت نداشته باشد، بلافاصله به دستورالعمل کلاسیک مانع حافظه برمی گردیم. نمودار قبلی ما این مورد بد را نشان نمیدهد، بنابراین اجازه دهید دادههای جدیدی را وارد کنیم.
اوه، این دادههای زیادی برای غربال کردن است. در حالی که باز هم خوب است که ببینیم سخت افزار در حین تقلید TSO چقدر از مسیر "بهینه" فاصله دارد، اما این چیزی نیست که در اینجا به آن اهمیت می دهیم. جالب است بدانید که این میکروبنچ تفاوت زیادی بین تراز و بدون تراز برای بار/فروشگاههای معمولی نشان نمیدهد، بنابراین ما فقط میانگین بین این دو را محاسبه کردیم. ما CPU x86 و دادههای ذخیره بار معمولی را از ستونهای ARM حذف خواهیم کرد، زیرا اینها مسیرهای رایج FEX نیستند. به این ترتیب ما دید هدفمندتری در مورد آسیب دیدگی بد دسترسی های حافظه بدون تراز تحت شبیه سازی خواهیم داشت.
اکنون که نمودار بسیار معقولتری از دادهها داریم، اجازه دهید از چپ به راست در این مورد قدم بزنیم و در مورد آنچه در حال وقوع است بحث کنیم.
این یکی بسیار جالب است، هر دو دستورالعمل بار تراز و بدون تراز تقریبا معادل هستند و در نویز قرار می گیرند. این بدان معنی است که حتی اگر بارهای نامتراز با یک جریمه مانع حافظه داده مواجه شوند، CPU فقط آن را کنترل می کند. این ممکن است موردی باشد که با توجه به اینکه عملکرد آن در مقایسه با سایر پلتفرمها چقدر پایینتر است، معیار با چیزهای دیگری در تنگنا قرار میگیرد.
در همین حال، طرف فروشگاه به دنبال آن نیست که در وضعیت خوبی حتی بدون همسویی قرار بگیرد. تقریبا در نمودار قابل مشاهده نیست! هنگامی که به فروشگاههای غیرهمتراز میرویم، ما به 8.5 درصد از عملکرد موفقیتآمیز نگاه میکنیم، اما از آنجایی که در حال حاضر بسیار پایین شروع کردهایم، تشخیص آن سخت است. این نیز کاملا در تضاد با دستورالعمل های معمول فروشگاه است که در این نیمکت 28 گیگابایت بر ثانیه دریافت می کنند.
تنها نتیجه ای که می توانیم در اینجا به آن برسیم این است که Ampere در حال بهینه سازی برای برخی از بار کاری کلاس سرور است و واقعا با رفتار سخت افزاری مصرف کننده مطابقت ندارد. این نقطه داده جالبی است، اما کاربران ما معمولا بازیهایی را روی این دسته از سختافزار اجرا نمیکنند.
این یک هسته CPU بسیار محبوب است که در داخل Qualcomm Snapdragon 8 Gen 3 زندگی می کند. ما فقط این یک هسته را از SoC آزمایش کردیم تا نمودار را غرق در داده ها نکنیم. تعداد بسیار زیادی از گوشی های دستی با این حمل می شوند، بنابراین هدف جالبی است. با توجه به اینکه تنها SoC تلفن همراه در این لیست است، این CPU واقعا به طرز شگفت انگیزی خوب عمل می کند. به طور کلی این نوع هسته با آنچه ما از آن انتظار داریم مطابقت دارد و روند گراف با نسل بعدی Cortex در آن نمودار دنبال می شود.
موضوعات اصلی برای این CPU این است که بارها و ذخیرههای همتراز آن نسبتا قدرتمند هستند و به ترتیب حدود 11.5 گیگابایت در ثانیه و 6.7 گیگابایت بر ثانیه هستند. نکته جالب این است که هنگام نیاز به مقابله با بارگذاریهای غیرهمتراز، عملکرد ضعیفی دارد، با زدن دستورالعملهای DMB، هسته تقریبا به طور مساوی بین بارها و ذخیرهسازیها در حدود 50 درصد در این معیار جریمه میشود.
به نظر میرسد این بدان معناست که CPU میتواند تعداد مناسبی از لودستورهای عرضهشده LRCPC را در پرواز نگه دارد، بنابراین دستورالعملهای DMB هنگام مواجه شدن با آنها آسیب بیشتری میزنند، اما باعث عملکرد جهانی نمیشود. فقط اینکه عملکرد 50 درصدی به دلیل تراز بودن نتیجه شگفت انگیزی نیست.
به دنبال X4، اجازه دهید به DGX Spark و هسته های X925 آن بسنده کنیم. این نه تنها یک هسته CPU جدیدتر از ARM است، بلکه روی سیستمی با پهنای باند حافظه بسیار بیشتر اجرا می شود. 273 گیگابایت بر ثانیه در پلتفرم در مقابل 76.8 گیگابایت بر ثانیه قبلی. این بدان معنی است که ما نتایج تقریبا مشابه X4 را دریافت می کنیم، فقط نمودار کمی بالاتر است. به اندازه کافی جالب توجه است که جریمه عملکرد برای دسترسی های غیر هم تراز تقریبا با X4 برابر است. اگرچه به نظر می رسد فروشگاه ها می توانند کمی سریعتر بهبود یابند، احتمالا به دلیل کمک سریعتر حافظه.
هیچ شگفتی در اینجا وجود ندارد، فقط عملکرد به طور مداوم در بین نسل ها مطابقت دارد.
این طراحی هسته CPU از پرس های کوالکام بسیار داغ است. پشتیبانی لینوکس هنوز در حال توسعه است، اما در حال حاضر نمایش قوی دارد. جالب ترین نتیجه از این در واقع از این واقعیت ناشی می شود که دستورالعمل های بار LRCPC تراز شده با عملکرد بارهای معمولی مطابقت دارند! این بدان معناست که در مورد یک برنامه کاربردی با رفتار خوب، ما معمولا می توانیم انتظار عملکرد کامل را داشته باشیم. این امر ادامه مییابد تا دستورالعملهای فروشگاه عرضه کاملا توانمند باشد، اگرچه با فروشگاههای معمولی که تنها ۶۸ درصد پهنای باند دارند، مطابقت ندارد. نمایش بدی نیست.
این CPU همچنین نمی تواند از جریمه لودستورهای غیرهمتراز با انتشار LRCPC فرار کند. سمت بار تقریبا با 70% جریمه عملکرد Cortex-X925 مطابقت دارد، احتمالا به این دلیل که Snapdragon X2 Elite نیز دارای چندین تن پهنای باند است. اما بخش فروشگاه در واقع با 43% عملکرد کمی بدتر می شود. حتی با این عملکرد دسترسیهای بدون تراز، این پلتفرم در واقع سریعتر از دسترسیهای تراز شده از پیشنهادات Cortex است.
یکی از چیزهای عجیب در مورد این پلتفرم این است که تبلیغ شده است که دارای "حافظه نهان L1 6 طرفه 96 کیلوبایتی کاملا منسجم با گرانول های همدوسی 64 بایتی" است. چیزی که از خوانش ما حاکی از این بود که دسترسیهای بدون تراز باید تأثیر بسیار کمتری بر عملکرد داشته باشند. جالب است... این را در نظر داشته باشید.
این مورد بزرگی است که باید در مورد آن صحبت کنیم. این همان چیزی است که یک تغییر دهنده بازی بود، آن "لحظه اپل" بود. این به همه نشان داد که ARM نه تنها امکان پذیر است، بلکه می تواند سریعتر نیز باشد. این اعداد در این نمودار شگفتانگیز هستند و نتیجه این است که اپل مدل حافظه TSO را مستقیما به سخت افزار خود چسبانده است. بهجای استفاده از دسترسیهای انتشار LRCPC برای این مورد، فقط ویژگی TSO آنها را فعال کردیم و نسخههای تراز شده اساسا با نسخه بدون تراز مطابقت دارند. شاید عملکرد 5٪ در فروشگاه ها ضربه بخورد؟ در مقایسه با هر دستگاه دیگری در آن نمودار، عملا چیزی نیست.
این در درجه اول به دسترسیهای بدون تراز است که دیگر نیازی به بکپچ کردن دستورالعملهای DMB در کد ندارند، زیرا سختافزار مستقیما آن را مدیریت میکند.
برای ما، این به معنای جدی گرفتن شبیهسازی x86 در ARM است و واقعا نشان میدهد که اپل اهمیت میداد که مشتریانش تجربه خوبی در اجرای نرمافزارهای بومی و شبیهسازی شده داشته باشند. آنها مشکل را دیدند و فقط آن را حل کردند و باعث شدند از بین برود. گفته میشود، وقتی حالت TSO فعال است، یک عملکرد عالی دریافت میکنید. در مقایسه با نمودار قبلی، تنها 76 درصد از عملکرد فروشگاه معمولی را دریافت می کند، و عملکرد بار اساسا مطابقت دارد. تحمل آن زمانی که همه چیز بسیار سریعتر است بسیار قابل تحمل است.
با پایان دادن به این بخش، باید در مورد یکی از بهبودهای عملکردی صحبت کنیم که همه این فروشندگان واقعا از آن پشتیبانی می کنند. این افزونه ای است که ARM به نام FEAT_LSE2 ایجاد کرده است که همه این پلتفرم های آزمایش شده آن را اجرا می کنند. ما قبلا در مورد اینکه چگونه دسترسیهای حافظه اکتسابی/LRCPC/release نیاز به همترازی طبیعی دارند تا خشم ناشی از خطاهای همترازی CPU را متحمل نشوند صحبت کردیم. ARM در واقع به این مشکل فکر کرد و این افزونه را پیاده سازی کرد که به شبیه سازی x86 (و احتمالا بارهای کاری دیگر) کمک می کند.
این برنامه افزودنی الزامات تراز نه تنها دستورالعملهای ذخیرهسازی بارگیری/آزادی/LRCPC/رهاسازی را کاهش میدهد، بلکه نیاز به خواندن، اصلاح و نوشتن اتمی را نیز کاهش میدهد!
متن اصلی (انگلیسی)
The scourge of x86 emulation
Article URL: https://fex-emu.com/Scourge-of-emulation/ Comments URL: https://news.ycombinator.com/item?id=49750094 Points: 246 # Comments: 67