Jump to page: 1 2
Thread overview
March 02, 2013

Bu aralar performansa çok taktığım için fark ettiğim bir ayrıntı.

auto dizi=[1,2,3,4];
auto b = *dizi.ptr;
auto c = dizi[0];

Burada ptr alma işlemimiz direk indekse erişmekten çok daha hızlı :)

Zekeriya

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

March 03, 2013

Bakalım neler oluyor...:)

void main() {
 ubyte[] dizi=[4, 5, 6 ];
 ubyte a = *dizi.ptr; // mov	BL,[RDX]
 ubyte b = dizi[0];   // mov	CL,[RDX]

 assert(a == b);      // cmp	BL,CL
}

Alıntı:

>

'_Dmain:
push RBP
mov RBP,RSP
sub RSP,018h
push RBX
'; ========== Bellekte 3 birimlik dizi kurar =========='
mov RSI,3
mov RDI,offset FLAT:_D11TypeInfo_Ah6__initZ@64
call _d_arrayliteralTX@PC32
'; ========== Her birime değerlerini yerleştirir =========='
mov byte ptr [RAX],4 '; a[0] = 4'
mov byte ptr 1[RAX],5 '; a[1] = 5'
mov byte ptr 2[RAX],6 '; a[2] = 6'
mov RCX,RAX
mov RAX,3
mov -010h[RBP],RAX '; a.length = 3'
mov -8[RBP],RCX '; &a'
mov RDX,-8[RBP]
mov BL,[RDX]
'; ========== Taşma var mı? (0 > a.length ise 1 satır atla) =========='
cmp qword ptr -010h[RBP],0
jne DEVAM
mov EDI,4 ' ; hata kodu olsa gerek...:)'
call _D4aptr7__arrayZ@PC32
DEVAM: mov RDX,-8[RBP]
mov RAX,-010h[RBP]
mov CL,[RDX]
'; ========== Eşitler mi? ( a != b ise 1 satır atla) =========='
cmp BL,CL
je ÇIK
mov EDI,6
call _D4aptr8__assertFiZv@PC32
ÇIK: xor EAX,EAX
pop RBX
leave
ret
nop
nop
'

Alıntı:

>

'_D4aptr7__arrayZ:
push RBP
mov RBP,RSP
sub RSP,010h
mov RSI,RDI
mov RDI,offset FLAT:_D4aptr12__ModuleInfoZ@64
call _d_array_bounds@PC32
nop
nop
'

Alıntı:

>

'_D4aptr8__assertFiZv:
push RBP
mov RBP,RSP
sub RSP,010h
mov RSI,RDI
mov RDI,offset FLAT:_D4aptr12__ModuleInfoZ@64
call _d_assertm@PC32
'

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

March 03, 2013

Gördüldüğü gibi aslında her ikisi de [RDX] denen yazmaçtan adresi alıyor. Bu da belki de "RoDataindeX" gibi bir şey olmalı? Tek farkı dizinin herhangi bir elemanına erişmeye kalktığımızda tıpkı assert()'de olduğu gibi bir denetleme mekanizmasına tabi tutulduğunu görüyoruz...

Biliyorsunuz; biz dizin değeri olarak en son 2 yazabilirdik. Ama senin örneğindeki adette elemana sahip olduğunu düşünseydik 3 de yazabilirdik. Derlerken hata vermezdi ama çalıştırdığımızda "Range violation" hatası alırdık...:)

İşte bu denetleme farkından dolayı yavaşlar. Aslında bir fark daha var, o da a'nın RDX'i çok dolambaçlı bir şekilde elde etmesi!

İlginç değil mi? Gerçi bu değer b için de kullanılıyor ya...

mov    RCX,RAX
:  :  :
mov    -8[RBP],RCX
mov    RDX,-8[RBP]
:  :  :
mov    BL,[RDX] // a = *dizi.ptr;

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

March 03, 2013

Belki de yanılıyorum; belleğin -8[RBP]'deki a değişkenine dizi.ptr'yi aslında üst satırda eşitliyor olmalı. BL ve CL yazmaçlarının kullanılmasının sebebi ubyte türündeki bir değeri karşılaştırma isteğimiz olabilir...

Ama neden [RCX]'i tıpkı [RDX] kullandığı gibi kullanmamış? İlginç!

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

March 03, 2013

Hatta çok daha ilginci, dizi.ptr taaa [RAX]'dan geliyor ve ne hikmetse RAX yazmaçı aynı zamanda dizinin uzunluğu için kullanılıyor. Bunlar her halde 64bit veri türünde genel (R... A-D...X) yazmaçlar. Belki başka derleyici de bunu daha akıllıca yapıyordur!

Çünkü bizim dizi.length'e ihtiyacımız yok ki, onu 3 rakamını koyduğu gibi doğrudan koyabilirdi. Bence bu kodlar çok aptalca çünkü RDX değişmediği halde bunu tekrar a değişkeni diye nitelendirdiğim -8[RBP]'den alıyor. Oysa _D4aptr8__assertFiZv alt yordamında RDX kullanılmıyo rki!

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

March 03, 2013

Hocam aklıma bir şey daha geldi. (Kodları incelemeye şimdi başlayacağım)

Acaba şu da etkilemiş olmasın. dizi[2] dediğimizde o veriyi kopyalamasından dolayı sorun çıkıyor olmasın? Ayrı bir d dosyası içerisinde bununla ilgili test yaptım hız olarak hiç fark çıkmadı. Ama VM içerisindeki kodlarda testimi yaptığımda ise kodlar aşağıdaki şekilde olunca ciddi bir hız farkı oluyor.

op_inc: asm{ call adresal; }
	datatypes[*registers[*cur.veriler.ptr].ptr].inc( registers[*cur.veriler.ptr] );

//Yavaş Olan kod
//	datatypes[registers[cur.veriler[0]][0]].inc( registers[cur.veriler[0]] );
	mixin(next);

Zekeriya

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

March 03, 2013

Hocam asm kodlarında bir tuhaflık mı var?

O çok görmeye alıştığım EAX EBX yerine RAX gelmiş :)

Zekeriya

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

March 03, 2013

Tuhaflığın sebebi 64 bit ortamda çalıştığım için olabilir ama tek tuhaflık bu değil. DMD dışında diğer derleyicilere de bakmamız lazım...:)

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

March 03, 2013

Evet tahmin ettiğim gibiymiş hatta karşıma daha fazla push komutu çıktı. Sanırım RSI'nın ortasında S harfi bir tür 64 bit stack olmalı. Çünkü dizi için bellekte yer ayrılan alt yordama geçemeden evvel 'mov RSI,3' yerine 32 bit'de sadece push 3 kullanılmış. Sanırm alt yordamda da (extrn _d_arrayliteralTX) pop yapılsa gerek. Kodu takip edemedim, çünkü external imiş...

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

March 03, 2013

Alıntı:

>

Tuhaflığın sebebi 64 bit ortamda çalıştığım için olabilir ama tek tuhaflık bu değil. DMD dışında diğer derleyicilere de bakmamız lazım...

Kesinlikle 64 bit olmasından dolayı :)

Zekeriya

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

« First   ‹ Prev
1 2