Değişkenleri bir döngünün arkasında mı yoksa bir döngünün içinde mi bildiriyorsunuz? - sayfa 11

 
Vict :

Baktım, tek bir derleyicinin https://en.cppreference.com/w/cpp/compiler_support modüllerini tamamlamadığı ortaya çıktı, bu yüzden izlenecek bir şey yok.

Yine de klan yoluyla modülleri kullanmayı başardı

 // module
export module M;
export int f( int x) {
     return 2 + x;
}

// main.cc
import M;
int main() {
         for ( int i = 0 ;  i < 1000000 ;  ++ i)
                f( 5 );
}

Optimizasyon ile derlenen döngü hiç yürütülmedi (yani optimizasyon, daha önce olduğu gibi yalnızca bir çeviri biriminde değil, çeviri birimi + dahil edilen modüller arasında gerçekleştirilir). Herhangi bir LTO olmadan. std c ++, tamamen modüllere, IMHO'ya geçmeye adaydır ve hiçbir soru olmayacaktır: "neden bu yapay örnekte çıplak bir döngü ile bu kadar yavaş."

 
Alexey Navoykov :

Öyle görünüyor ki, bu durumda bile, her seferinde hafızayı ayırdığını ve sildiğini öğrendiler:


Bu arada, geçen sefer yanlış sonuçlar vermiş olabilirim. Büyük olasılıkla x86 modundaydı. Şimdi x64'te test ediyorum - C ++'daki sonuçlar çok daha iyi:

1) ~ 2000ms

2) ~200ms (3 kez hızlandırılmış)

Doğru, Studio'yu da en son sürüme güncelledim, görünüşe göre bu da etkiledi, çünkü. x86 bile artık geçmiş ölçümlerden daha hızlı.

Eh, genel olarak, şimdi C ++ Sharpe'ı utanç verici bir şekilde tüketmiyor. Toplamda yaklaşık 3 kez

Hmm, yani çöp toplayıcı yok, tanımla ilgili sorular neler?

Hızdan bahsetmiyorum, hafızadan bahsediyorum
 
Alexey Navoykov , constexpr dizesinin ve vektörünün C++20'ye sürüklendiği ortaya çıktı. Onlar. tüm bu testlerimiz tek bir satırda bakım talimatı dahi almayacak, peki, oraya bellek ayırın vs. (pekala, eğer karakterler dönemin yaralarından gelmiyorsa tabii). Güzel.
 
Vict :
Alexey Navoykov , constexpr dizesinin ve vektörünün C++20'ye sürüklendiği ortaya çıktı. Onlar. tüm bu testlerimiz tek bir satırda bakım talimatı dahi almayacak, peki, oraya bellek ayırın vs. (pekala, eğer karakterler dönemin yaralarından gelmiyorsa tabii). Güzel.

Yani bunun için her şeyi açıkça constexpr olarak işaretlemek gerekiyor, yoksa bunu otomatik olarak mı belirleyecek?

Gördüğüm kadarıyla sorun standartta değil, derleyicide. Artık fazlalığı kesmesini engelleyen bir şey var mı? Sharp derleyicisinin normal şekilde optimize etmesi ve aynı Microsoft'un artı sürümünün başarısız olması özellikle garip. Görünüşe göre, ortak bir temele sahip olmaları gerekir (bu tür yapıları optimize etmek açısından)

 
Alexey Navoykov :

Yani bunun için her şeyi açıkça constexpr olarak işaretlemek gerekiyor, yoksa bunu otomatik olarak mı belirleyecek?

otomatik olarak, derleme zamanında bilinen satırların dizeye girmesi yeterlidir. Bu dizeyle yapılan tüm işlemler (arama, değiştirme, ...) derleme zamanında aynı olacaktır (Sharpe ve Mkl'nin derleme zamanında da örneklerimizi dikkate aldığından şüpheleniyorum). Planlar, tüm kapsayıcıları constepxr yapmaktır. Onlar. artık derleyicinin ruh haline bağlı değildir, ancak standart tarafından garanti edilir, örneğin şablon parametresini dize ayrıştırma yoluyla hesaplayabilirsiniz. İşte ilginç olan - yeni/sil'in artık constexpr olduğu ortaya çıktı (contexpr türleri için)?

Gördüğüm kadarıyla sorun standartta değil, derleyicide. Artık fazlalığı kesmesini engelleyen bir şey var mı? Sharp derleyicisinin normal şekilde optimize etmesi ve aynı Microsoft'un artı sürümünün başarısız olması özellikle garip. Görünüşe göre, ortak bir temele sahip olmaları gerekir (bu tür yapıları optimize etmek açısından)

Avantajların optimizasyon fırsatları açısından bir dezavantajı vardır - bu yalnızca bir çeviri birimi çerçevesindedir (eğer LTO kullanmıyorsak). Tabii ki, tüm std'yi başlık dosyalarında yapabilirsiniz, ancak yapmazlar (derleme süresinden dolayı mı?). Sharp with modüller bu konuda daha ileri düzeydedir. Ancak c++ 20'de bu, modüllerin gelişiyle yakında düzeltilecektir. Ayrıca std'yi oraya aktarma planları da var (önce modüller test edilecek ve daha sonra dosyalanacaklar). Ama VS modüllerde zaten std yapmış gibi görünüyor, deneyebilirsiniz (yukarıdaki bağlantıyı bıraktım).

Ama yine de ısrar ediyorum - döngüden sonra bildirmek daha iyidir (eğer temel bir tür değilse).

 
Alexey Navoykov :

İlgi uğruna, C# ile de test etmeye karar verdim. Sonuçlar yalnızca pratik olarak hız açısından birbirinden farklı olmakla kalmaz, aynı zamanda C++'dan çok daha hızlı çalışırlar.

Sonuçlar:

Toplam: 894782460, Süre: 69ms

Toplam: 894782460, Süre: 56ms

Ve işte C++'daki karşılığı:

Toplam: 894782460, Süre: 2947ms

Toplam: 894782460, Süre: 684ms

VS 2019'da test ediliyor . Tüm optimizasyonlar etkinleştirildi.

Fırında böyle C ++)

ps C#'daki sonuçlar testten teste fark edilir şekilde atlar, ancak ortalama olarak her iki seçeneğin de hızda aynı olduğu ortaya çıkar.

İpucu: Sharpe'de string temel tiptir, artılarda artılar üzerine yazılan sınıftır. Sharp'taki varyantta, dize ataması artılarda bir kez - 10e6 kez gerçekleşir. Sonuç olarak, profesyoneller daha hızlıdır, ancak kod yazarken bir düşünürü dahil etmeniz ve Boeing'de bir Kızılderili kamburunu şekillendirmemeniz gerekir.
 
SeriousRacoon :
İpucu: Sharpe'de string temel tiptir, artılarda artılar üzerine yazılan sınıftır. Sharp'taki varyantta, dize ataması artılarda bir kez - 10e6 kez gerçekleşir. Sonuç olarak, profesyoneller daha hızlıdır, ancak kod yazarken bir düşünürü dahil etmeniz ve Boeing'de bir Kızılderili kamburunu şekillendirmemeniz gerekir.
Hayır, tamamen farklı bir konu. Dizenin orada bir sınıf olduğunu unuttum ve nesnenin kendisine değil, atanmış bir referansları var. Dolayısıyla bu formdaki karşılaştırma yanlıştır.
 

Bu arada, optimizasyon hakkında. Derleyicinin burada sizin için bir şeyi optimize etmesini ister misiniz?

mutex mtx;

void thread_0() {
        while (true) {
                do_task_0();
                {
                        lock_guard < mutex > lck{mtx};
                        do_task_1();
                }
                do_task_2();
                {
                        lock_guard < mutex > lck{mtx};
                        do_task_3();
                }
                do_task_4();
        {
}
void thread_1() {
        while (true) {
                do_task_5();
                {
                        lock_guard < mutex > lck{mtx};
                        do_task_6();
                }
                do_task_7();
                {
                        lock_guard < mutex > lck{mtx};
                        do_task_8();
                }
                do_task_9();
        {
}
 
Alexey Navoykov :
Hayır, tamamen farklı bir konu. Dizenin orada bir sınıf olduğunu unuttum ve nesnenin kendisine değil, atanmış bir referansları var. Dolayısıyla bu formdaki karşılaştırma yanlıştır.
Referans (işaretçi) nereye atanır? artı dize sınıfında? Ne diyorsun, arabellek ayırma ve kopyalama var.
 
SeriousRacoon :
Referans (işaretçi) nereye atanır? artı dize sınıfında? Ne diyorsun, arabellek ayırma ve kopyalama var.

keskin hakkında konuşuyor