Hatalar, hatalar, sorular - sayfa 2165

 

Negatif değerler için bir optimizasyon grafiği oluşturmuyorum.

Optimizasyon sonuçlarında veriler var.

Uzman Danışmanlarınızda negatif değerler ayarlamaya çalışın. Değerler doğrulama için * -1 olabilir.

 
Renat Fatkhullin :

Çek şunu gösterdi:

  1. Doğrudan CPU talimatlarına eşlenen SQRT

  2. SQRT + matematiksel hesaplamalar dallar olmadan yapılır ve bir komut (128 bit veri) için aynı anda iki kök hesaplanır

    Bu kod, aşağıdaki montajcı SSE koduna dönüşür:
    Sonuçta bu bir sanat eseri. Montajcı komutunun 4 çağrısı için 8 kök hesaplanır. Bir aramada iki çift sayı hesaplandı.

  3. Bir dizideki işlemler sırasında, çift -> tamsayı indeks dönüşümünde kontroller, dallanma ve kayıplarla her şey normal şekilde gider

  4. Bu örnekte dizilerle çalışırken, performans üzerinde çok kötü bir etkisi olan sürekli bir FPU / ALU karışımı vardır.

  5. Dinamik bir diziye erişimin optimizasyonu övgünün ötesinde mükemmeldir. Ancak FPU/ALU işlemlerini karıştırmak + çift çevirmek -> tamsayı + dallara ayırmak zaman kaybettirir

Genel sonuç: MQL5'teki matematik, mükemmel optimizasyon sayesinde kazanır. Kaybeden diziler değil, matematik kazanır.

Değerli bilgiler için çok teşekkürler.

Haber tabii ki daha sevindirici. Bu gerçekten havalı!

MQ'nun yakışıklı olduğunu her zaman söylemişimdir!

Ancak, veri türlerini karıştırırken son derece dikkatli olmanız gerektiğini de anlıyorum. Ama önceden uyarılmış, önceden hazırlanmış demektir.
Bu ışıkta geliştiricilerden bazı öneriler almak harika olurdu.

Şimdi hem sıradan değişkenlerin hem de dizilerin türlerini deneyeceğim. Ne olduğu ilginç.

 
Renat Fatkhullin :

denendi.

Bir şekilde bulmacalarım uymuyor.

İki seçenek yaptı. İlk - maksimuma, her şeyi int türüne aktardı. İkincisi ikili.

Evet, biraz daha hızlı oldu. Ancak ana frenler hala mevcut.

İşte int seçeneğine sahip ana fren bloğu:

 if (arr)
        {   // расчет квадратных корней через массив значений SQRT[]
         D1=SQRT[((X1-X)*(X1-X)+(Y1-Y)*(Y1-Y))];
         D2=SQRT[((X2-X)*(X2-X)+(Y2-Y)*(Y2-Y))];
         D3=SQRT[((X3-X)*(X3-X)+(Y3-Y)*(Y3-Y))];
         D4=SQRT[((X4-X)*(X4-X)+(Y4-Y)*(Y4-Y))];
         D5=SQRT[((X5-X)*(X5-X)+(Y5-Y)*(Y5-Y))];
         D6=SQRT[((X6-X)*(X6-X)+(Y6-Y)*(Y6-Y))];
         D7=SQRT[((X7-X)*(X7-X)+(Y7-Y)*(Y7-Y))];
         D8=SQRT[((X8-X)*(X8-X)+(Y8-Y)*(Y8-Y))];
        }

sadece int tipi vardır ve tip karıştırma yoktur. Aynı zamanda, SQRT dizisinin kendisi int oldu.

Yalnızca yüzde 10 daha hızlı çalışır.

C varyantı benzer bir resmi ikiye katlar.

Eh, her şey aynı, sadece bir durumda sqrt () işlevi hesaplanırken, türlerin bir karışımı var.

Ve ikinci durumda, bir int dizisine erişilir ve tip karıştırma yoktur ve teoride sadece ALU kullanılmalıdır.

Ve ikinci seçenek 3 kat daha yavaşken. Eh, biri ne derse desin, nedeni bir dizidir.

Ve bir önemli nokta daha.

int örneğinde, tuval 100x100 ise, yani. bu ayarlarla

daha sonra diziye erişirken hız kazancı elde ederiz.

Onlar. 20.000 boyutunda bir SQRT dizisi kullandığımızda %15-20, 3.000.000 kullandığımızda ise tamamen aynı matematikle %200 kaybediyoruz.

Dizinin boyutu frenlerin nedeni mi?

Dosyalar:
LSD_double.mq5  10 kb
LSD_int.mq5  10 kb
 

İnsanlar, modern C++ derleyicilerinin çıktısını anlama yeteneğini uzun süredir kaybettiler.

Ek olarak, koddan salata sosu / çöpünüz var, bu da saf aksiyomlar oluşturmak için neredeyse sıfır fırsat anlamına geliyor “eğer böyle koşullar varsa, sonuç böyle olacaktır”. Yani, son optimizasyon her şeyi o kadar çok yeniden oluşturacak ki, koddaki yetersiz değişikliklerle bile hipotezleriniz yüzde onlarca farklı sonuç verecektir.

8 kökün 4 montaj talimatına sıkıştırılmasına bir kez daha bakın ve hiçbir şey iddia etme, talep etme veya mantığınıza hitap etme şansınız olmadığını anlayın. Optimize ediciler, uzun süredir programcıların erişemeyeceği aşkın seviyelerde çalışmaktadır.

Derleyicinin kökleri ayrıştırma şekli bir sanattır. Ve en basit sınırlamayı bile anlamadan onu dizilerle yenmeye çalışıyorsunuz - bir diziden okumak zaten bir başarısızlık. Mükemmel kayıt işlemi ve toplu köke karşı dallanma (cezalar) ve sık önbellek kayıplarıyla bellek tırmanışı.

İşlemcinin L1 / L2 / L3 önbelleklerini hiç bilmediğiniz için “neden küçük bir tamponda daha hızlı çalışıyor, ancak büyük bir tamponda sağır edici bir şekilde birleşiyor” sorusunu soruyorsunuz. Önbelleğe basın - hızlı bir şekilde sayılır. Vurmadı - üst önbellek veya bellekten birkaç düzine veri okuma döngüsü bekleyin.
 
Renat Fatkhullin :

İnsanlar, modern C++ derleyicilerinin çıktısını anlama yeteneğini çoktan kaybetti.

Ek olarak, koddan salata sosu / çöpünüz var, bu da saf aksiyomlar oluşturmak için neredeyse sıfır fırsat anlamına geliyor “eğer böyle koşullar varsa, sonuç böyle olacaktır”. Yani, son optimizasyon her şeyi o kadar çok yeniden oluşturacak ki, koddaki yetersiz değişikliklerle bile hipotezleriniz yüzde onlarca farklı sonuç verecektir.

8 kökün 4 montaj talimatına sıkıştırılmasına bir kez daha bakın ve hiçbir şey iddia etme, talep etme veya mantığınıza hitap etme şansınız olmadığını anlayın. Optimize ediciler uzun zamandır programcıların erişemeyeceği aşkın seviyelerde çalışıyor.

VS ile karşılaştırma sonuçlarınızı çok iyi görebiliyorum ve bundan çok memnunum.
Ama soru açık kalıyor.

Kaotik çalışma kodu için özür dilerim, ancak bu yalnızca kodun bu bölümü ve iki yürütme seçeneğinin karşılaştırılması ile ilgilidir:

 if (arr)
        {   // расчет квадратных корней через массив значений SQRT[]
         D1=SQRT[((X1-X)*(X1-X)+(Y1-Y)*(Y1-Y))];
         D2=SQRT[((X2-X)*(X2-X)+(Y2-Y)*(Y2-Y))];
         D3=SQRT[((X3-X)*(X3-X)+(Y3-Y)*(Y3-Y))];
         D4=SQRT[((X4-X)*(X4-X)+(Y4-Y)*(Y4-Y))];
         D5=SQRT[((X5-X)*(X5-X)+(Y5-Y)*(Y5-Y))];
         D6=SQRT[((X6-X)*(X6-X)+(Y6-Y)*(Y6-Y))];
         D7=SQRT[((X7-X)*(X7-X)+(Y7-Y)*(Y7-Y))];
         D8=SQRT[((X8-X)*(X8-X)+(Y8-Y)*(Y8-Y))];
        }
 else // расчет квадратных корней через функцию кв. корня sqrt()
        {
         D1=( int ) sqrt ((X1-X)*(X1-X)+(Y1-Y)*(Y1-Y));
         D2=( int ) sqrt ((X2-X)*(X2-X)+(Y2-Y)*(Y2-Y));
         D3=( int ) sqrt ((X3-X)*(X3-X)+(Y3-Y)*(Y3-Y));
         D4=( int ) sqrt ((X4-X)*(X4-X)+(Y4-Y)*(Y4-Y));
         D5=( int ) sqrt ((X5-X)*(X5-X)+(Y5-Y)*(Y5-Y));
         D6=( int ) sqrt ((X6-X)*(X6-X)+(Y6-Y)*(Y6-Y));
         D7=( int ) sqrt ((X7-X)*(X7-X)+(Y7-Y)*(Y7-Y));
         D8=( int ) sqrt ((X8-X)*(X8-X)+(Y8-Y)*(Y8-Y));
        }

Burada çöp yok.

" Dinamik dizi erişim optimizasyonu övgünün ötesinde mükemmel" dediniz.

Ama... önceki mesajıma bakın.

Son denememi nasıl açıklarsınız?:

"Yani, boyutu 20.000'lik bir SQRT dizisi kullandığımızda %15-20 kazanıyoruz ve 3.000.000 kullandığımızda tamamen aynı matematikle %200 kaybediyoruz.

Dizinin boyutu frenlere neden olur mu?"

 

Önceki cevabımı dikkatlice okuyun - kesin cevapla birlikte eklendi.

Sorularınızı basit bir şekilde açıklayacağım: İşlemcilerin tasarımına ilişkin beş teknik makaleyi performans ve onu etkileyen faktörler açısından dikkatlice okuyun. Onsuz, tartışamazsınız çünkü temel şeyleri açıklamanız gerekir.

 
Renat Fatkhullin :

Derleyicinin kökleri ayrıştırma şekli bir sanattır. Ve en basit sınırlamayı bile anlamadan onu dizilerle yenmeye çalışıyorsunuz - bir diziden okumak zaten bir başarısızlık. Mükemmel kayıt işlemi ve toplu köke karşı dallanma (cezalar) ve sık önbellek kayıplarıyla bellek tırmanışı.

İşlemcinin L1 / L2 / L3 önbelleklerini hiç bilmediğiniz için “neden küçük bir tamponda daha hızlı çalışıyor, ancak büyük bir tamponda sağır edici bir şekilde birleşiyor” sorusunu soruyorsunuz. Önbelleğe basın - hızlı bir şekilde sayılır. Vurmadı - üst önbellek veya bellekten birkaç düzine veri okuma döngüsü bekleyin.
Renat Fatkhullin'in fotoğrafı.

Önceki cevabımı dikkatlice okuyun - kesin cevapla birlikte eklendi.

Sorularınızı basit bir şekilde açıklayacağım: İşlemcilerin tasarımına ilişkin beş teknik makaleyi performans ve onu etkileyen faktörler açısından dikkatlice okuyun. Onsuz, tartışamazsınız çünkü temel şeyleri açıklamanız gerekir.

Yaşasın!!!
En sonunda!
Sen Renat, içinden kerpetenle çekilmen gerekiyor.

Şimdi resim benim için daha net.

Derleyicinize sürdüğümde yanılmışım. İtiraf ediyorum, şeytan kandırdı. Bunun sebebinin işlemcinin sınırlı önbellekleri olduğu tahmin edilebilirdi. Modern işlemcilerde gerçekten kötüyüm ve gerçekten bu konuda okumam gerekiyor.

Ama yine de, bu kodu yazmam boşuna değildi - bir laboratuvar faresi ve bu dalgayı kaldırdı.

Bu yüzden, bu konuyu okuyan programcılar için, bu dalganın sonucunda kişisel olarak bulmayı başardıklarımı özetleyeceğim:

  • sqrt() işlevi ve büyük olasılıkla diğer birçok temel işlev çok hızlıdır ve derleyici düzeyinde değil, işlemci düzeyinde yürütülür.
  • MQL5 derleyicisi, matematiksel mantığı optimize etmede o kadar güçlüdür ki, modern VS C++ derleyicisi bunu kolayca yapabilir. Bu çok ilham verici.
  • Kaynak yoğun görevlerde türleri karıştırmamaya çalışmanız önerilir. Karıştırma türleri, hesaplama hızının düşmesine neden olur.
  • BOYUT ÖNEMLİ! (yani dizinin boyutu :)) çok seviyeli işlemci önbelleğinin özellikleri ve sınırlı boyutu nedeniyle. Programcıların dizilerin toplam boyutunu takip etmeleri ve büyük dizilerin kullanımının hesaplama hızını önemli ölçüde etkileyebileceğini anlamaları gereksiz olmayacaktır. Anladığım kadarıyla, toplam hacmi yaklaşık 512 kB'yi geçmeyen, yani double türünde ~ 65000 veya int türünde ~ 130000 eleman olan dizilerin nispeten rahat çalışmasından bahsediyoruz.

Bu bilgilerden yola çıkarak kodu düzeltmeye gitti. Dizilerin boyutunu sık sık kötüye kullandım.

Herkese teşekkürler!

 

artı düğmesine basıldığını veya bırakıldığını nasıl anlarız?

fare tekerleğinin tıklamasını yakalayabilirsiniz, ancak fare kullanılmıyorsa ne yapmalı?

 
Alexandr Bryzgalov :

artı düğmesine basıldığını veya bırakıldığını nasıl anlarız?

fare tekerleğinin tıklamasını yakalayabilirsiniz, ancak fare kullanılmıyorsa ne yapmalı?

Gerekirse zorla basabilir veya sıkabilir mi?

CHART_CROSSHAIR_TOOL

Orta fare düğmesine basarak "artı işareti" aracına erişimi etkinleştirin / devre dışı bırakın

bool (varsayılan doğru)

 
Alexey Viktorov :

Gerekirse zorla basabilir veya sıkabilir mi?

CHART_CROSSHAIR_TOOL

Orta fare düğmesine basarak "artı işareti" aracına erişimi etkinleştirin / devre dışı bırakın

bool (varsayılan doğru)

Anladığım kadarıyla, bu yalnızca araca erişim, ancak kapatma değil.