جایگزینی SHA1 با xxHash؛ اجرای سریعتر ادیتور Unreal
خلاصهٔ کاملتر
نویسنده که قبلاً هم چند بار سرعت بالا اومدن ادیتور Unreal رو بهتر کرده، میگه معمولاً سراغ بخشهایی مثل کامپایل شیدر نمیره، چون فکر میکنه تیم Epic خوب بهینهشون کرده. ولی یه بار توی پروفایلر روی تابع «Compile Global Shader Map» زوم کرد و دید زیرش داره از SHA1 برای هش کردن شیدرها استفاده میشه.
مشکل اینجاست که SHA1 یه هش رمزنگاریه، یعنی طوری طراحی شده که امن باشه نه سریع. تازه سالهاست که از نظر امنیتی هم شکسته شده. نویسنده به تستی از Aras Pranckevičius اشاره میکنه که SHA1 رو فقط برای نشون دادن فاصلهٔ سرعتش با بقیه آورده بود. چیزی که هش میشه هم سورس کامل شیدرهاست، با همهٔ کامنتها و متن کپیرایت. یعنی دادهٔ زیادیه که هیچ اطلاعات حساسی هم توش نیست و به هش امن نیازی نداره.
راهحل، استفاده از xxHash بود که یه هش غیررمزنگاری و سریعه و پیادهسازیش از قبل توی کدبیس Unreal وجود داشت. نویسنده میگه هشهای سریعتری هم هست، ولی استفاده از چیزی که داخل انجین تست شده، سادهتر و مطمئنتره. تغییرش از اونچه فکر میکرد جاهای بیشتری رو درگیر کرد، چون هر جا هش ذخیره یا پاس داده میشد باید عوض میشد. یه فایدهٔ جانبی هم داشت: اندازهٔ هش از ۲۰ بایت به ۸ بایت رسید.
برای تست، پروژهٔ نمونهٔ Electric Dreams رو ۵ بار با تغییر و ۵ بار بدون اون باز کرد و با Superluminal پروفایل گرفت. توی نسخهٔ اصلی، ۱۲.۹۰ ثانیه زمان CPU توی FSHA1::Update صرف میشد و توی نسخهٔ جدید فقط ۱.۵۹ ثانیه توی FXxHash64Builder::Update. یعنی حدود هشت برابر سریعتر. نویسنده توضیح میده که این عدد جمع زمان همهٔ threadهاست و اثر واقعی روی زمان بالا اومدن ادیتور، تقریباً این عدد تقسیم بر تعداد هستههاست.
Pull request این تغییر خیلی زود توسط Epic پذیرفته شد، هرچند هنوز merge نشده. تیم Epic دو تا اصلاح هم روش انجام داد: xxHash رو داخل یه struct به اسم FShaderHash گذاشت تا اگه بعداً خواستن الگوریتم رو دوباره عوض کنن، فقط یه جا لازم باشه تغییر بدن. یه خطای کامپایل توی buildهای غیرادیتور رو هم درست کرد که نویسنده چون فقط build ادیتور رو تست کرده بود، ندیده بود.
نکات کلیدی:
- ادیتور Unreal سورس شیدرها رو با SHA1 هش میکرد که برای این کار لازم نیست.
- با xxHash زمان CPU این بخش از ۱۲.۹۰ ثانیه به ۱.۵۹ ثانیه رسید.
- اندازهٔ هر هش ذخیرهشده از ۲۰ بایت به ۸ بایت کم شد.
- Epic تغییر رو پذیرفت و هش رو داخل FShaderHash گذاشت تا عوض کردنش در آینده راحت باشه.
- عددها جمع زمان همهٔ threadهاست؛ اثر روی زمان واقعی تقریباً تقسیم بر تعداد هستههاست.