x86 emülatör ekibinin o kadar kötü bir kod bulup emülasyon sırasında düzeltmesi
(devblogs.microsoft.com)- x86-32 emülatörü, başka işlemcilerde x86-32 kodunu çalıştırmak için ikili çeviriyle yerel kod üretiyordu ve yorumlayıcı tabanlı yaklaşıma kıyasla büyük bir performans artışı sağlıyordu
- Bu emülatör, x86-32’yi bir bytecode gibi görüp emülatörün de bir JIT derleyici gibi çalıştığı bir yapı olarak anlaşılabilir
- Bir programın yığında yaklaşık 64KB bellek ayırıp bunu başlatması gerekiyordu; yaygın yöntem, yığın yoklamasından sonra yığın işaretçisini azaltıp küçük bir döngüyle belleği başlatmaktı
- Söz konusu kodun derleyicisi, döngü yerine 65.536 ayrı bayt yazma komutu üretti; her komut 4 bayt olduğundan 64KB veriyi başlatmak için 256KB kod gerekiyordu
- Emülatör ekibi bu işlevi algılayan özel bir kodu çeviriciye ekledi ve bunu eşdeğer kısa bir döngüyle değiştirecek şekilde işledi
Arka plan: x86-32 emülatörü ve ikili çeviri
- Windows, x86-32 dışındaki başka işlemcilerde çalışan sistemler için bir dönem x86-32 işlemci emülatörü içeriyordu
- Bu örneğin hangi işlemciye uygulandığı özgün yazıda belirtilmiyor
- Söz konusu emülatör, özgün x86-32 koduyla eşdeğer davranışı gerçekleştiren yerel kod üretmek için ikili çeviri kullanıyordu
- Bu yöntem, yorumlayıcı tabanlı emülasyona göre kayda değer bir performans artışı sağlıyordu
- x86-32’yi bir bytecode, emülatörü de bir JIT derleyici olarak düşünmek mümkün
Sorunlu kod: 64KB yığın belleğini başlatma
- Bir programın yığında yaklaşık 64KB bellek ayırıp bunu başlatması gerekiyordu
- Standart yöntem önce yığın yoklaması yaparak 64KB belleğin kullanılabilir olup olmadığını doğrulamaktı
- Ardından yığın işaretçisinden 65.536 çıkarılır ve küçük, sıkı bir döngüyle bellek başlatılırdı
Derleyicinin aşırı döngü açması
- Bu kodu derleyen derleyici, her baytı başlatan bir döngü üretmedi
- Bunun yerine döngüyü 65.536 ayrı “belleğe bayt yazma” komutuna açarak üretti
- Her komutun uzunluğu 4 bayttı
- Sonuç olarak 64KB veriyi başlatmak için 256KB kod gerekiyordu
Emülatör ekibinin yanıtı
- Emülatör ekibi bu işlevi algılayan özel kodu çeviriciye ekledi
- Algılanan işlev, eşdeğer davranışı gerçekleştiren kısa bir döngüyle değiştirildi
- Bu işlem, özgün program kodunu aynen çevirmek yerine emülasyon sırasında verimsiz kod desenlerini daha derli toplu bir biçime dönüştürüyordu
1 yorum
Lobste.rs görüşleri
Raymond Chen’e loop unrolling açıklayan yorumu epey beğendim
Bu tür yazıları okuyan herkes tüm arka plan bilgisine sahip olmuyor; bu yüzden daha fazlasını öğrenmeye yardımcı olacak ipuçlarını takdir eden çok kişi var
https://joelonsoftware.com/2004/06/…
Bunun Alpha üzerinde olduğunu sanıyorum. Çünkü o platformun x86 emülatörü için gerçekten çok fazla çalışma yapılmıştı