Merhaba, Ziyaretçi. Lütfen giriş yapın veya üye olun.

Kullanıcı adınızı, parolanızı ve aktif kalma süresini giriniz

  Gelişmiş Arama
insanın içinde varsa, commodore.gen.tr açığa çıkarır bunu.. bir nevi retro olaylarının dolunayıyız.(Arda)
Sayfa: [1] 2   Aşağı git
Yazdır
Gönderen Konu: Döngüler Neden Yavaş?  (Okunma Sayısı 12482 defa)
0 Üye ve 1 Ziyaretçi konuyu incelemekte.
programci42
Üye
***
Mesaj Sayısı: 227


Üyelik Bilgileri
« : Kasım 29, 2018, 20:01:04 ÖS »

Not: Aynı konuyu donanımhaber de açtım ama kimse cevap vermiyor nasıl bir yer anlamadım isminde donanım olduğu için mi acaba
------------------------------------------------------------------------------------

Arkadaşlar şöyle bir sorunum var döngüler çok yavaş çalışıyor neden ki bu bana çok saçma geliyor.
Yani günümüzdeki bilgisayarlar artık eskisi gibi kağnı hızında çalışmıyor yok 8 çekirdekli 4.2 GHz işlemci, 8 Gb ram 2400 MHz gibi vs ama abi bi döngü yazıyorsun 0 dan başla 1 milyona kadar say diyorsun 10 dk bekletiyor ya, bunu hızlandıramazmıyız veya bu işlemi saniyeler içinde yapabilecek bir kod var mı? Aşağıda örnek bir döngü var mesela.

Bu arada visual studio kullanıyorum kod yazdığım dil C#.Net

for (int x = 0; x<1000000; x++)
{
//işlemler
}
Logged
CaiSSoN
Uzman
*****
Mesaj Sayısı: 348


C64 Fan


Üyelik Bilgileri WWW
« Yanıtla #1 : Kasım 29, 2018, 20:15:05 ÖS »

Not: Aynı konuyu donanımhaber de açtım ama kimse cevap vermiyor nasıl bir yer anlamadım isminde donanım olduğu için mi acaba

donanımhaber derken? 
Logged

emarti
Uzman
*****
Mesaj Sayısı: 2.627


Only Amiga Makes It Possible █


Üyelik Bilgileri WWW
« Yanıtla #2 : Kasım 29, 2018, 21:15:53 ÖS »

for döngüsündeki hız birçok faktöre bağlı:
1. İşlemler olarak belirttiğin kısımda kodu ne kadar optimize ettiğin ile orantılı
2. Ne tür bir işlem yaptığın ile
3. İşlemler kısmı tamamen boş ise hızlı olmalı
4. Bu hız yetmiyorsa .Net'ten uzaklaş
5. Sanırım max. hız Assembler ile olur.
Logged

https://github.com/emartisoft My GitHUB | http://csdb.dk/scener/?id=26786 My CSDB | https://c64kernal.com Genesis

READY.
SYS(64767): EMARTI
programci42
Üye
***
Mesaj Sayısı: 227


Üyelik Bilgileri
« Yanıtla #3 : Kasım 29, 2018, 21:30:03 ÖS »

işlemler kısmında yaptığım şeyler öyle çok alengırikli muazzam hesaplama becerisi isteyen işlemler değil yani şöyle söyliyim en fazla 20 satır bilemedin  30 satırlık bir kod kısmı var döngü içinde yaptığım işlemler basit matematiksel hesaplama işlemleri topla çıkar sonucu şu değişkene at onu al böl şuraya at şu sayıdan küçükse şuraya yaz büyükse şuraya yaz eşitse bilmem şu dizide aynısı var mı bak varsa onları şurda sırala gibi yani kodların tamamı ram de çalışan işlemler öyle harddiskten okuma yazma yok veritabanından oku yaz olayı da yok anladınız sanırım.
Logged
programci42
Üye
***
Mesaj Sayısı: 227


Üyelik Bilgileri
« Yanıtla #4 : Kasım 29, 2018, 21:34:22 ÖS »

Ya bize lisede flowchart diye dandik bir program gösterirlerdi alogiritma mantığını öğrenmek için orda delay diye bir ayar vardı onu düşürünce kod hızlı çalışır yükseltince de yavaşlardı bizde programı takip ederdik modern dillerde böyle bir şansınımız yok mu acaba? Abi sonuçta bilgisayarı satarken ne diyorlar bu bilgisayar öyle hızlı böyle hızlı kaç saniyede bilmem kaç milyar işlem yapar işlemcisi F-35 savaş uçağından bile hızlı ışık hızında yetişemezsin e hani kardeş durum bu saniyede milyar kere milyar işlem yapan işlemci 0 dan 1 milyona sayarken takılıyor.
Logged
emarti
Uzman
*****
Mesaj Sayısı: 2.627


Only Amiga Makes It Possible █


Üyelik Bilgileri WWW
« Yanıtla #5 : Kasım 29, 2018, 22:04:24 ÖS »

Burada senin kodladığın C# satırları olarak değil bunun makine diline çevrilmiş halindeki işlem sayısı önemlidir. Assembler kodlamada olarak araştırırsan saniyedeki yaptığı işlem sayısını daha iyi anlamış olacaksın. Buradaki assembly .NET assembly değil.
Logged

https://github.com/emartisoft My GitHUB | http://csdb.dk/scener/?id=26786 My CSDB | https://c64kernal.com Genesis

READY.
SYS(64767): EMARTI
ilkerficicilar
Uzman
*****
Mesaj Sayısı: 1.122


Üyelik Bilgileri WWW
« Yanıtla #6 : Kasım 29, 2018, 22:54:10 ÖS »

Şimdi son cümlen abi ile başlıyor ortalarda kardeşe dönüyor gerçi ama tahminen çoğumuz iki kat yaşlı olduğumuzdan anladık sanırım.

Öncelikle teorik limitimizi bulalım. Örneğin, bugün 4.9GHZ'lik i7-9700K gibi bir işlemci yaklaşık 40-50 Gflops bandında bir double precision floating point işlem hızına sahip. Ancak, sen özel bir çaba göstermedikçe kodun sequential çalışacak, yani çekirdek sayısı burada hız arttırmıyor. O yüzden benchmark programının rapor ettiği Gflops'u işlemci sayısına bölüyoruz, bu örnek için 8'e. Yani, multitaskingi kapatırsak/hiçbir interrupt vb. olmazsa, kodu assembly ile yazarsak ve hiçbir bellek erişimi olmayıp tüm işlemler registerlar ile halledilirse 5 ila 6.25 Gflops'umuz var kullanacak.

Döngü 1E6 defa döndüğüne göre, hızımızdan 6 sıfır atarsak, döngünün 1 saniyede tamamlanması için döngü içine en çok ne kadar floating point işlem sokabileceğimizi hesaplayabiliriz. Yani döngünün içinde en çok 5-6 bin double precision çarpma bölme varsa, bellek erişimi yoksa, döngü içindeki işlemler işlemci pipeline'larında mikrokod boşluğuna yol açmayacak bir yapıdaysa, multitasking yoksa/interruptlar kapalıysa ve assembly ile  yazdıysan 1 saniyede bitmesi gerek. Teorik limitimiz bu.

Şimdi geriye, bu üst limitten multitasking kayıplarını, bellek erişimi sırasında yaşanan kayıpları, branch prediction kayıplarını, döngü içinin harcadığı cycle'ları ve C#'ın overhead'ini düşmek kalıyor... Demek bunlar ilgili örnekte maksimum 600 kat kadar yavaşlatıyormuş.

Çözüm olarak yapılabilecekler arasında, kodu elle paralelleştirmek, mesela döngü içi hesapları birbirinden bağımsız 8 parçaya bölerek 8 thread halinde çalıştırmak, işlem sıralarıyla oynayarak döngü içini olabildiğinde optimize etmek/pipelinelerı dolu tutmak, döngü içindeki işlemleri işlemcinin çekirdek başına düşen L2 cache'ini hemen tüketmeyecek bir sırayla yaptırmak ya da grafik kartını programlamayı öğrenerek SIMD tarzı paralellikle sorunu çözmek yer alıyor.
Logged

http://cbm.ficicilar.name.tr/ - Commodore Hacking
yucelbilik
Üye
****
Mesaj Sayısı: 484



Üyelik Bilgileri WWW
« Yanıtla #7 : Kasım 29, 2018, 23:08:01 ÖS »

Günümüz bilgisayarlarının 0 dan 1 milyona kadar sayarken döngü içerisinde yavaş kalması için muazzam işlemler yaptırmak gerekir diye düşünüyorum veya yaptırsak bile herhangi bir çıktı üzerine yazdırmaz isek (ekran, yazıcı) yine yavaşlamaz, Şöyle bir örnek vereyim: Önceden QBASIC de yazdığım Sayısal loto programı iç içe 6 döngüden oluşuyor ve kolon sayısı 13 milyon küsür, programı çalıştırınca eğer sadece toplam kolon sayısını istersek 0,8 sn de sonuç veriyor, yok eğer ben 13 milyon kolonu ekranda görmek istiyorum dersek işlem 4 dakika 05 sn sürüyor, bu farkın sorumlusu döngüler arasında çıktı istememiz.
Logged

yb
i_r_on
Uzman
*****
Mesaj Sayısı: 2.873



Üyelik Bilgileri WWW
« Yanıtla #8 : Kasım 29, 2018, 23:39:18 ÖS »

İlk sırada yapman gerekeni söyleyeyim sana. Algoritma öğrenmen gerekiyor.

Bize dandik flowchart gösterdiler dedikleri günlere geri dönüp biraz daha ciddi yaklaşman lazım olaya.

1 milyonluk bir döngüde C# ile basit bir iki aritmetik işlem yaptırdım. Programın çalışması saniye bile sürmedi.

Demek ki senin yaptırdığın işlemler programın karmaşıklığını arttıran işlemler.

Algoritma öğrenmeye başladığında ilk duyacağın kelime karmaşıklık. 1 milyonluk döngün dakikalar alıyorsa demek ki programını N küp karmaşıklığına götüren bir işlem yapıyorsun.

Ekipçe yazdığımız bir kodda elemanlardan birinin kodunu review ederken N kare  karmaşıklık tespit etmiştim. Malesef Linq gibi Lambda expression'lar gibi kavramları doğrudan kullanmaya çalışan, temeli de sağlam olmayan yazılımcılar bu hatayı yapıyorlar.

20000 elemanlı bir dizi için 20000 defa dönülüyor,
Diziye .Where deyip bir değeri arama yapıyor.

20000 sayısı kulağa sempatik geliyor değil mi? 20000 * 20000? 400.000.000 ediyor. Dizide arama yapmak için çok lüks. Lineer search'ün karmaşıklığı N seviyesinde. Dış döngü ile beraber tüm karmaşıklık N*N oluyor.

Kod review aşamasında bunu görmüşüm ama düzeltilmemiş. Uygulamayı başka bir yere kurduk, çalıştırdık. Çalışması saat sürdü bitmiyor. Debug edince baktım buralarda takılıyor kod, o sıra dank etti.

Geçici çözüm, dış döngü sayısı müdahale edebileceğimiz bir şeydi, onu 2000'e indirdim. 2000 * 2000 = 4.000.000... Program 10 kat hızlandı..

En hızlı hali bu mudur? Değil pek tabii, o dizide linear search yerine daha önce sıralanarak binary search yapılabilir. Düz dizi yerine Hashtable / Dictionary kullanılabilir. Dictionary kullanıldığı vakit karmaşıklık N'e düşüyor. yani 20000 defa dönülerek aynı iş yapılabilir. Orjinaline göre 20000 kat daha hızlanıyor.

Özetle : for'u kaça kadar saydırdığından ziyade, tüm işlem bloğunu dikkate aldığında karmaşıklığın ne oluyor önemli olan o. Visual studio'nun profiling özelliği var, bunu kullanıp kodun hangi bloğunda daha fazla işlemci tüketildiğini görerek orayı optimize etmek için yoğunlaşabilirsin.

Bir konu daha var o da I/O... o kod bloğunda herhangi bir network / disk ve benzeri I/O erişimi yapıyorsan vay haline.  Oraya gereksiz bir Console.WriteLine bile koysan programın yavaşlar.

Logged

Every imagination is one's self reflection but not every self reflection is imagination. <I.R.on - 2001>

twitter | blog
wizofwor
Genel Yönetici
*****
Mesaj Sayısı: 4.798


Gosub ile gidilen yerden goto ile dönen adam


Üyelik Bilgileri WWW
« Yanıtla #9 : Kasım 30, 2018, 00:58:44 ÖÖ »

Küçük bir test yaptım. Aşağıdaki kodu metin editöründe yazıp looptest.c olarak kaydettim. Derledim ve gtime komutuyla çalıştırarak çalışma süresini ölçtüm.

Benim sistemimde 0.02 saniye gösteriyor. Dolayısı ile bir yerlerde bir hata yaptığını düşünüyorum.

Kod:
#include <stdlib.h>

int main(void) {
    int i, s;

    for (i = 0; i < 10000000; ++i) {
        s += 1;
    }

    return 0;
}

Sistemim i5 2.7GHz işlemcili late 2012 iMAC / OSX Majove
Logged

Levent (Lvnt)
Uzman
*****
Mesaj Sayısı: 2.392



Üyelik Bilgileri
« Yanıtla #10 : Kasım 30, 2018, 11:20:05 ÖÖ »

Küçük bir test yaptım. Aşağıdaki kodu metin editöründe yazıp looptest.c olarak kaydettim. Derledim ve gtime komutuyla çalıştırarak çalışma süresini ölçtüm.

Benim sistemimde 0.02 saniye gösteriyor. Dolayısı ile bir yerlerde bir hata yaptığını düşünüyorum.

Kod:
#include <stdlib.h>

int main(void) {
    int i, s;

    for (i = 0; i < 10000000; ++i) {
        s += 1;
    }

    return 0;
}

Sistemim i5 2.7GHz işlemcili late 2012 iMAC / OSX Majove
Sırf meraktan deneyeyim dedim. Döngü sayısı 10'000'000

Optimizasyonsuz derledim. Atom n2600'de 0.033s.
Logged

Use the brute force, Luke
programci42
Üye
***
Mesaj Sayısı: 227


Üyelik Bilgileri
« Yanıtla #11 : Şubat 16, 2019, 00:45:53 ÖÖ »

Evet arkadaşlar uzun bir ara oldu konu açılalı ama demek istediğim şey tam olarak şuydu; arkadaşlar tek satırlık bir kod yazıp denemiş aynısını ben de yaptım doğru 1 sn bile sürmedi ancak benim ekteki kodları biraz incelerseniz daha iyi olur kodların çıktısı da ekteki excel dosyasında var.

Kısaca kodların ne yaptığını anlatayım SQL Server veritabanında kayıtlı olan müşterilerin güncel borç - alacak ve kalan bakiyesini çekiyor sistemde kayıtlı sadece 360 müşteri var ilk for döngüsü 360 a kadar sayıyor yani müşteri sayısı artarsa değişiyor tabi güncel rakama göre diğer iç döngü ise müşteriyle yapılan borç alacak hareketlerini çekiyor bu döngü sayısıda müşteriyle yapılan işleme göre değişiyor.
Bu bilgileri düzgün ve formatlı bir biçimde renklendirerek, fontunu ayarlayarak, yazı tipini ve boyutunu belirleyip, arkplan rengini belirleyip, gerekli hücreleri daraltıp veya genişletip, gerekli hücreleri birleştirip, yazı hizalamasını sağa veya sola göre ayarlayıp, düzgün bir excel dosyası çıktısı oluşturuyor ekteki örneğe bakabilirsiniz.

Ben size sadece örnek bir excel çıktısı gönderdim yaklaşık 200 satır ve 5 müşterinin hesap bilgileri var ama bu bilgileri excele yazması yaklaşık 10 sn sürdü sistemdeki tüm müşterilerin hesaplarını bu şekilde yazdırdığımızda bizi bekletiyor tabi bilgisayarın gücüne göre de değişmekle birlikte 5 - 10 dk kadar falan bekliyoruz tabi çok uzun bir süre değil ancak yine de sinir bozucu müşteri sayısı 2000 - 5000 olan firmalar aynı raporu bunlarda isterse şayet o zaman adamlar 1 saat mi bekleyecek nasıl çözebiliriz kodları biraz inceleyin bazı gereksiz kodlar var onlara takılmayın arayüzle ilgili.
Asıl işlemler döngülerde yapılıyor her hücrenin içindeki değeri yazı tipi yazı rengi genişliği arkaplan rengi vs belirleniyor tabi bu da iş yükünü artırıyor ama çıktıyı bu şekilde isteyen müşteri biz değil yapacak bir şey yok bu şekilde istiyorlarsa bekleyecekler o zaman ya da sizin önerdiğiniz bir yöntem var mı?

*  (19.73 KB - Yükleme: 254 kez.)
* excel.zip (15.92 KB - Yükleme: 218 kez.)
Logged
programci42
Üye
***
Mesaj Sayısı: 227


Üyelik Bilgileri
« Yanıtla #12 : Şubat 16, 2019, 00:46:57 ÖÖ »

Yanlış eklenmiş aşağıda doğru eklenti var.

*  (19.73 KB - Yükleme: 211 kez.)
Logged
amenofis
Üye
**
Mesaj Sayısı: 48


Üyelik Bilgileri
« Yanıtla #13 : Şubat 16, 2019, 01:53:07 ÖÖ »

Kod aralarında zaman ölçümü yapmalı ve nerede tıkanıklık olduğunu bulmanız lazım. Muhtemelen en yavaş olan kısım sql sorgusudur çünkü hdd/ssd okuma yapıyor.

Performans ölçümü konusunda yardımcı araçlar var. Mesela profiler var, hangi metodun ne kadar süre çalıştığını söyler size.

Düz okuma yazma haricinde hiçbir işlemi kesinlikle hdd üzerinde yapmayın. Belleğe yükleyin, işlemleri bellek üzerinde yapın ve toplu olarak harddisk'e yazın.
Logged
eins
Uzman
*****
Mesaj Sayısı: 1.816


A.K.A. deliMawi


Üyelik Bilgileri
« Yanıtla #14 : Şubat 16, 2019, 02:29:31 ÖÖ »

Tam da yerine geldin bence. 4.2 GHz işlemci, 8 Gb ram 2400 MHz yavaşlığından bahsediyorsan, hemen bir C64 edinip, 1MHz işlemci, 64KB RAM de biraz çalış, gerçekten güncel problemlerinde çok yardımcı olacaktır sana.

Bunu dalga geçmek için söylemiyorum, C64 tecrübelerimi halen profesyonel hayatımda o bahsettiğin güncel donanımlarda çalışan kodlarımı optimize ederken kullanırım.
Logged

Doberman ♦ megaOne ♦ HDMI-64 ♦ HDMI-520 ♦ NewSchool
Sayfa: [1] 2   Yukarı git
Yazdır
Gitmek istediğiniz yer: