c++ ile asal sayı hesaplanırken donanımlar arası hesaplama süresi farkı.

Şimdi javascript ile yazdım 10 milyona kadar olan süre 1976.5 milisaniye, 10 bin ise 0.8000000000465661 milisaniye javascript c++ den daha hızlı çıktı. ancak şuan işyerinin pc'si ile yazıp denedim intel i5 8250u işlemci var eve gidince kendi pc'mde de denerim.

Ayrıca evde bilgisayarıma linux'un bir dağıtımını kurup c++, python ve js de tekrar deneyeceğim. Bu konuyu kafaya taktım çok ilginç buldum... İşletim sistemlerinin neye öncelik tanıdığını görür gibiyim windows için kullanıcı işlemleri sistem işlemlerinden daha az önemli gibi görünüyor bu sebeple c++ win'de yavaş çalışıyor olabilir.


.html olarak kaydedin:
<!DOCTYPE html>
<html lang="tr">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title></title>
</head>
<body>
    <label for="limit">Sayı gir:</label>
    <input type="number" id="limit" name="limit">
    <button onclick="asalBul()">Asal Sayıları Bul</button>
    <div id="asalSayiId"></div>
    <div id="islemZamaniId"></div>

    <script>
        function asalmi(n) {
            if (n <= 1)
                return false;
            if (n <= 3)
                return true;

            if (n % 2 == 0 || n % 3 == 0)
                return false;

            for (let i = 5; i * i <= n; i = i + 6)
                if (n % i == 0 || n % (i + 2) == 0)
                    return false;

            return true;
        }

        function asalBul() {
            const limit = parseInt(document.getElementById("limit").value);
            const startTime = performance.now();

            let primeNumbers = [];
            for (let i = 2; i <= limit; ++i) {
                if (asalmi(i)) {
                    primeNumbers.push(i);
                }
            }

            const endTime = performance.now();
            const islemZamani = endTime - startTime;

            const div = document.getElementById("asalSayiId");
            div.textContent = "Asal sayılar: " + primeNumbers.join(", ");

            const islemZamaniDiv = document.getElementById("islemZamaniId");
            islemZamaniDiv.textContent = "İşlem süresi: " + islemZamani + " milisaniye";
        }
    </script>
</body>
</html>
 
Son düzenleme:
Kötü yazılmış bir device driver linux'ta da benzer problemler yaratabilir, ama aradaki fark, eğer açık kaynak driver'lar dışında birşey kurmuyorsan, o driver'ların kaynak kodunu birden fazla kişi görüyor ve potansiyel problemler yakalanabiliyor. Ama windows'da herkes kafasına göre driver yazıyor, kimseye de hesap vermiyor.
 
Ben de şimdi denedim. Javascript 2200 ms gibi bir sürede hesaplıyor. Ama javascript testini tam eşdeğer yapmamışsın. Javascript'te sonucu bir array'e koyuyorsun, C++ da ekrana yazdırıyorsun. İkincisi çok daha uzun sürer.

Eğer C++ kodunu da bir array'e yazdıracak şekilde revize ettiğimde, C++ kodu 1524 milisaniyede tamamlandı.

Kod:
#include <iostream>
#include <chrono>
#include <vector>

bool asalmi(int n) {
    if (n <= 1)
        return false;
    if (n <= 3)
        return true;

    if (n % 2 == 0 || n % 3 == 0)
        return false;

    for (int i = 5; i * i <= n; i = i + 6)
        if (n % i == 0 || n % (i + 2) == 0)
            return false;

    return true;
}

static std::vector<int> asallar;

int main() {
    int limit;


    std::cout << "sayı gir: ";
    std::cin >> limit;

    auto start_time = std::chrono::steady_clock::now();


    std::cout << "Asal sayılar:" << std::endl;
    for (int i = 2; i <= limit; ++i) {
        if (asalmi(i)) {
            asallar.push_back(i);
        }
    }
    std::cout << std::endl;


    auto end_time = std::chrono::steady_clock::now();
    auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time);
    std::cout << "İşlem süresi: " << duration.count() << " milisaniye" << std::endl;

    std::cout << "asal adedi = " << asallar.size();
    return 0;
}
 
PC de delphi ile 1milyara kadar asal taramasi sonucunda 279720284 tane asal sayiyi 7600 ile 7700 ms araliginda buluyor.

Yanlis mi kodladim 10 milyona kadar 2797207 asal sayi buluyor ve sadece 78 ms suruyor.

Delphi kullanmadım ama bildiğim kadarıyla o da derleme yapıp makina kodu üreten bir dil. O açıdan bakınca C++ ile benzer sonuçlar alınmasını beklerim. Ben şimdi C++ ile 1 milyarı denedim, sonuç 1014707 milisaniye çıktı, yani 16 dakika.

Hadi diyelim senin bilgisayar en son çıkan işlemciyi kullanıyor, ama gene de 1014 saniyede yapılan bir işi 7 saniyeye indirmesi çok mantıklı gelmedi bana. Saat hızı açısından benim makina da 4 GHz lere çıkıyor, son makinalar da öyle. Yapılan işlem integer işlemi, benzer clock hızına sahip iki işlemcinin birbirine büyük fark atma şansı yok, yapılacak iş belli ve bir birkaç cycle'da tamamlanıyor zaten.

Bu ancak şöyle hızlandırılır: Eğer makinanda mesela 24 tane çekirdek varsa, 1 milyarı 24 e bölersin. Her bir parçayı da ayrı çekirdekte incelersin. Böylece süreyi 24 te birine indirmiş olursun.
 
1 den 10 milyona ya da 1 milyara kadar ardisil sayilar icinde kac tane asal sayi buluyorsunuz?

En azindan yazdigim kodun dogru olup olmadigina karar vereyim.
 
1 miyar için bulunan asal sayısı 50847534
 
@ShadowMan sana güzel bir proje, işi tüm çekirdeklere yayarak yapmayı dene :) Çekirdek sayısı oranında düşüş elde etmen lazım. Önce iki çekirdek, sonra 4 çekirdek şeklinde deneyebilirsin. Benim makinada 8 çekirdek var, aynı kodu burada da deneriz ve orantılı olarak zamanın azaldığını görebiliriz.
 
Ben de şimdi denedim. Javascript 2200 ms gibi bir sürede hesaplıyor. Ama javascript testini tam eşdeğer yapmamışsın. Javascript'te sonucu bir array'e koyuyorsun, C++ da ekrana yazdırıyorsun. İkincisi çok daha uzun sürer.

Eğer C++ kodunu da bir array'e yazdıracak şekilde revize ettiğimde, C++ kodu 1524 milisaniyede tamamlandı.

Kod:
#include <iostream>
#include <chrono>
#include <vector>

bool asalmi(int n) {
    if (n <= 1)
        return false;
    if (n <= 3)
        return true;

    if (n % 2 == 0 || n % 3 == 0)
        return false;

    for (int i = 5; i * i <= n; i = i + 6)
        if (n % i == 0 || n % (i + 2) == 0)
            return false;

    return true;
}

static std::vector<int> asallar;

int main() {
    int limit;


    std::cout << "sayı gir: ";
    std::cin >> limit;

    auto start_time = std::chrono::steady_clock::now();


    std::cout << "Asal sayılar:" << std::endl;
    for (int i = 2; i <= limit; ++i) {
        if (asalmi(i)) {
            asallar.push_back(i);
        }
    }
    std::cout << std::endl;


    auto end_time = std::chrono::steady_clock::now();
    auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time);
    std::cout << "İşlem süresi: " << duration.count() << " milisaniye" << std::endl;

    std::cout << "asal adedi = " << asallar.size();
    return 0;
}
Evet hocam js ile yazarken diziye push ettiğimi şimdi farkettim.. Sizin kodunuzu akşam derler sonucu yazarım. Proje konusunda haklısınız işi çekirdeklere bölmek daha çok hızlandırır bunu nasıl yapacağımı düşüneceğim çünkü normal hayatta web uygulamaları yapan biriyim bu zamana kadar hiç çoklu çekirdek kullanmadım js'in asenkron yapısı işimi gördü hep.
 
Evet Javascript'in performansı beni şaşırttı. Bu kadar iyi olmasını beklemiyordum. Şimdi o kadar online grafik oyunlarının ve online CAD programların nasıl çalışabildiği mantık yapıyor.
 
Kodumda hata varmis.

10 milyona kadar 664579 tane asal sayiyi 1578 ms'de buldu.
1 milyar icin 50847534 tane asal sayiyi 1105642 ms'de buldu.
 
1'i teste sokturmuyorum.
if (n <= 3) then exit; satiri da kaldirilir ve 3 den buyuk sayilar teste gonderilirse milyar bazindaki arastirmalarda msler bazinda cok zaman fark eder.

function asalmi(n:integer):boolean;
var i:integer;
label dongu;
begin

result:=true;
if (n <= 3) then exit;
if (n and 1)=0 then begin result:=false; exit; end;
if (n mod 3)=0 then begin result:=false; exit; end;

i:=5;

Dongu:
if i*i<=n then
begin
if ((n mod i)=0) or ((n mod (i+2))=0) then begin result:=false; exit; end ;
i:=i+6;
goto Dongu;
end;
exit;
end;
 
1711737717317.png
 
Son düzenleme:
Kod:
package main

import (
    "fmt"
    "runtime"
    "sync"
    "time"
)

func main() {
    startTime := time.Now()

    numCores := runtime.NumCPU()
    runtime.GOMAXPROCS(numCores)

    const startNum = 0
    const endNum = 10000000
    var wg sync.WaitGroup

    step := (endNum - startNum + 1) / numCores
    primes := make([]int, 0)
    var mutex sync.Mutex

    for i := 0; i < numCores; i++ {
        wg.Add(1)
        go func(i int) {
            defer wg.Done()
            from := startNum + i*step
            to := from + step
            if i == numCores-1 {
                to = endNum + 1
            }
            foundPrimes := findPrimes(from, to)
            mutex.Lock()
            primes = append(primes, foundPrimes...)
            mutex.Unlock()
        }(i)
    }

    wg.Wait()
    endTime := time.Now()
    duration := endTime.Sub(startTime)

    fmt.Printf("0 ile 10 milyon arasında %d adet asal sayı bulundu.\n", len(primes))
    fmt.Printf("İşlem süresi: %d ms\n", duration.Milliseconds())
}

func findPrimes(from, to int) []int {
    primes := make([]int, 0)
    for num := from; num < to; num++ {
        if isPrime(num) {
            primes = append(primes, num)
        }
    }
    return primes
}

func isPrime(num int) bool {
    if num <= 1 {
        return false
    }
    for i := 2; i*i <= num; i++ {
        if num%i == 0 {
            return false
        }
    }
    return true
}
Kodu şimdi tekrar güncelledim mutex vs ekledim. İşlemi biraz daha tam performans olacak şekilde güncellendim. Ms düşürmeyi başardım :D
İşlemcinin max cpu bilgisini alır. Ona göre tüm cpuları eş zamanlı kullanacak şekilde bir waitgrup oluşturur.
Burada işlemlerin hepsi sıraya alınır ve max işlemci sayısına göre çalışmaya başlar ve Mutex ile bir işlem yapılırken diğer işlemin çakışmasını engelliyoruz.

16 Çekirdek:
Kod:
Sonuç:
0 ile 10 milyon arasında 664579 adet asal sayı bulundu.
İşlem süresi: 1265 milisaniye
 
Son düzenleme:
100 milyona kadar saydırdım hadi yarış :)

Screenshot 2024-03-29 at 16.53.46.png


Bu da 1 milyara kadar:

Screenshot 2024-03-29 at 16.58.26.png


Algoritma farklı ama haberiniz olsun :p
 

Çevrimiçi personel

Forum istatistikleri

Konular
6,950
Mesajlar
118,743
Üyeler
2,822
Son üye
lalemasall

Son kaynaklar

Son profil mesajları

hakan8470 wrote on Dede's profile.
1717172721760.png
Dedecim bu gul mu karanfil mi? Gerci ne farkeder onu da anlamam. Gerci bunun anlamini da bilmem :gulus2:
Lyewor_ wrote on hakan8470's profile.
Takip edilmeye başlanmışım :D ❤️
Merhaba elektronik tutsakları...
Lyewor_ wrote on taydin's profile.
Merhabalar. Elektrik laboratuvarınız varsa bunun hakkında bir konunuz var mı acaba? Sizin laboratuvarınızı merak ettim de :)
Lyewor_ wrote on taydin's profile.
Merhabalar forumda yeniyim! Bir sorum olacaktı lcr meterler hakkında. Hem bobini ölçen hemde bobin direnci ölçen bir lcr meter var mı acaba?
Back
Top