Büyük Afiş - JIT Derlendi (Düşük iyidir)
- es1024 - 81.2 puan (çalışan bir derleyici dahil!)
- Kieth Randall - 116 puan
- Ell - 121 puan
Büyük Afiş - Yorumlandı (Düşük iyidir)
- Martin Büttner - 706654 puan (yaklaşık 2 saat).
- criptych - 30379 puan (97 saniye)
Göreviniz, kabul etmeyi seçerseniz, mümkün olan en küçük bayt kodu yorumlayıcısını / VM'yi yazmaktır. VM / yorumlayıcı, aşağıda belirtilen dille küçük bir CISC mimarisi kullanır (işlemler boyut olarak değişebilir). Tamamlandığında, doğru çıktının yazdırıldığını kanıtlamak için 3 CPU kaydının değerini yazdırmanız gerekir (3,126,900,366).
Derleyici
Kendi testlerinizi yapmak istiyorsanız, aşağıda bir derleyici yayınlanır. Testlerinizi cevabınızla birlikte göndermekten çekinmeyin.
"VM" Özellikler
VM'de 3 adet 32 bit imzasız integral kaydı vardır: R0, R1, R2. Onaltılık biçimde 0x00, 0x01 ve 0x02 olarak temsil edilirler.
Aşağıdaki işlemler desteklenmelidir:
Biçim [ad] [... işlenenler ...], [onaltılık op kodu] [... işlenenler tekrarlandı ...]
- YÜKLE [kayıt] [4 bayt değer], 0x00 [kayıt] [4 bayt değer]
- PUSH [kayıt], 0x02 [kayıt]
- POP [kayıt], 0x03 [kayıt]
- ADD [kayıt, 1 bayt] [kayıt, 1 bayt], 0x04 [kayıt] [kayıt]
- SUB [kayıt, 1 bayt] [kayıt, 1 bayt], 0x05 [kayıt] [kayıt]
- MUL [kayıt, 1 bayt] [kayıt, 1 bayt], 0x06 [kayıt] [kayıt]
- DIV [kayıt, 1 bayt] [kayıt, 1 bayt], 0x07 [kayıt] [kayıt]
- JMP [kod satırı, 4 bayt], 0x08 [4 bayt kod satırı numarası]
- CMP [kayıt, 1 bayt] [kayıt, 1 bayt], 0x09 [kayıt] [kayıt]
- BRANCHLT [kod satırı, 4 bayt], 0x0a [4 bayt kod satırı numarası]
Bazı notlar:
- Yukarıdaki matematik işlemleri, çıktıyı ilk kayda yerleştirerek 2 kaydın değerlerini toplar.
- Karşılaştırma operatörü olan CMP, 2 yazmaçın değerlerini karşılaştırmalı ve çıktıyı, şube talimatlarında ileride kullanılmak üzere bazı dahili bayraklarda (uygulamaya özel olabilir) depolamalıdır.
- BRANCH CMP'den önce çağrılırsa, BRANCHEQ çağrılmadıkça "VM" dallanmamalıdır.
- PUSH / POP şaşırtıcı bir şekilde yığından sayıları itin veya pop.
- Jump ve Branch operatörleri, ikili bir adrese değil, belirli bir işleme (kod satırı) atlar.
- Şube işlemleri karşılaştırmayı yapmaz. Aksine, yürütmek için çıktıyı son karşılaştırmadan alırlar.
- Şube ve Jump işleçleri sıfır tabanlı bir satır numarası dizinleme sistemi kullanır. (Örneğin, JMP 0 ilk satıra atlar)
- Tüm işlemler sıfıra taşan ve tamsayı taşmasına istisna atmayan imzasız sayılar üzerinde gerçekleştirilmelidir.
- Sıfıra bölmeye izin verilmez ve bu nedenle programın davranışı tanımlanmaz. Şunları yapabilirsiniz (örneğin) ...
- Programın çökmesi.
- VM'nin yürütülmesini sonlandırın ve geçerli durumuna döndürün.
- "ERR: Bölme 0" mesajını göster.
- Programın sonlandırılması, talimat göstergesinin programın sonuna geldiği zaman tanımlanır (boş olmayan bir program olduğu varsayılabilir).
Çıktı Çıktı tam olarak bu olmalıdır (yeni satırlar dahil)
R0 3126900366
R1 0
R2 10000
Puanlar
Puanlar aşağıdaki formüle göre hesaplanır:Number Of Characters * (Seconds Needed To Run / 2)
Farklı zamanlara neden olan donanım farklılıklarından kaçınmak için, her test ubuntu sunucusunda veya Windows 8'de bilgisayarımda (i5-4210u, 8GB ram) çalıştırılacaktır, bu nedenle yalnızca Dual G5'te derlenen bazı deli-egzotik çalışma zamanlarını kullanmamaya çalışın Tam 762,66 mb boş RAM ile Mac Pro.
Özel bir çalışma zamanı / dil kullanıyorsanız, lütfen bunun için bir bağlantı gönderin.
- İlgili taraflar için, test kodunu (C # ile yazılmış) buraya gönderdim: http://pastebin.com/WYCG5Uqu
Test programı
Fikir buradan geldi , bu yüzden programlarının biraz değiştirilmiş bir sürümünü kullanacağız.
Program için doğru çıktı: 3.126.900.366
C dilinde:
int s, i, j;
for (s = 0, i = 0; i < 10000; i++) {
for (j = 0; j < 10000; j++)
s += (i * j) / 3;
}
Kodda: [R0, s'yi temsil eder, R1, j, R2, i]
LOAD R0 0
LOAD R2 0 <--outer loop value
LOAD R1 0 <--inner loop value
--Begin inner loop--
PUSH R1 <--push inner loop value to the stack
MUL R1 R2 <--(i*j)
PUSH R2
LOAD R2 3
DIV R1 R2 <-- / 3
POP R2
ADD R0 R1 <-- s+=
POP R1
PUSH R2
LOAD R2 1
ADD R1 R2 <--j++
POP R2
PUSH R2
LOAD R2 10000
CMP R1 R2 <-- j < 10000
POP R2
BRANCHLT 3 <--Go back to beginning inner loop
--Drop To outer loop--
LOAD R1 1
ADD R2 R1 <--i++
LOAD R1 10000
CMP R2 R1 <-- i < 10000
LOAD R1 0 <--Reset inner loop
BRANCHLT 2
İkili / onaltılı olarak:
0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x02 0x00 0x00 0x00 0x00
0x00 0x01 0x00 0x00 0x00 0x00
0x02 0x01
0x06 0x01 0x02
0x02 0x02
0x00 0x02 0x00 0x00 0x00 0x03
0x07 0x01 0x02
0x03 0x02
0x04 0x00 0x01
0x03 0x01
0x02 0x02
0x00 0x02 0x00 0x00 0x00 0x01
0x04 0x01 0x02
0x03 0x02
0x02 0x02
0x00 0x02 0x00 0x00 0x27 0x10
0x09 0x01 0x02
0x03 0x02
0x0a 0x00 0x00 0x00 0x03
0x00 0x01 0x00 0x00 0x00 0x01
0x04 0x02 0x01
0x00 0x01 0x00 0x00 0x27 0x10
0x09 0x02 0x01
0x00 0x01 0x00 0x00 0x00 0x00
0x0a 0x00 0x00 0x00 0x02
Bonus Puanlar (Efektler çarpımsal olarak uygulanır) Örneğin, eğer üçü için de hak kazanırsanız, ((karakterler * 0.50) * 0.75) * 0.90
- Tercüman aslında bir JIT derleyicisi ise% 50 azalma
- Herhangi bir döngü açma / anlamlı optimizasyon uygularsa% 25 azalma.
- VM'yi aşağıdakilerle genişletirseniz% 10 azalma
- BRANCHEQ [kod satırı, 4 bayt] (Eşitse şube - opcode 0x0b)
- BRANCHGT [kod satırı, 4 bayt] (Şundan büyükse şube - opcode 0x0c)
- BRANCHNE [kod satırı, 4 bayt] (Eşit değilse şube - opcode 0x0d)
- RLOAD [register 1] [register 2] (kayıt 2 değerini kayıt 1 - opcode 0x01'e taşıyın).
İzin verilmeyen
- Test vakasının programa hazırlanması yasaktır. Bayt kodunu STDIN'den veya bir dosyadan kabul etmelisiniz (Hangisi önemli değil).
- Programı çalıştırmadan çıktıyı iade etme.
- VM gereksinimini aldatmayı düşünebileceğiniz başka herhangi bir yol.
CMP
Daha küçük veya eşitlik kontrolü var mı ? Ve sonucuna ne olur?
MUL
ve DIV
ayrıca daha az belirtiliyor. İmzalanmalı veya imzalanmamalı mı? Çarpma taşması durumunda ne olur?