Fórum Root.cz

Hlavní témata => Vývoj => Téma založeno: Michal Štrba 12. 04. 2013, 18:27:27

Název: C# je rychlejší než C/C++?
Přispěvatel: Michal Štrba 12. 04. 2013, 18:27:27
Nazdar!

Urobil som maly test a vysledok ma velmi prekvapil. Napisal som tento program v C#:

Kód: [Vybrat]
using System;

namespace TestApp
{
class Program
{
public static void Main(string[] args)
{
int n = 0;
for (var i = 0; i < 999999999; i++) {
n++;
}
}
}
}

a ten isty program v C:

Kód: [Vybrat]
int main() {
  int n = 0;
  for (int i = 0;  i < 999999999;  i++) {
    n++;
  }
}

C program je skompilovany pomocou gcc, C# je skompilovany v MonoDevelop. Toto su casy behu programov odmerane pomocou utility time:

C
real   0m3.507s
user   0m3.504s
sys   0m0.000s


C#
real   0m0.707s
user   0m0.692s
sys   0m0.012s


Z toho vyplyva, ze (samozrejme pre dany program, ktory je vsak dost vseobecny ohladne vykonu) C# je takmer 5x rychlejsi ako C.

Co na to hovorite?

PS: nie nijako som sa nepomylil!
Název: Re:C# je rychlejsi ako C/C++?!?!
Přispěvatel: Michal Štrba 12. 04. 2013, 18:33:59
Operacny system: Ubuntu 13.04
Mono 2.10.8.1
GCC 4.7.3
Název: Re:C# je rychlejsi ako C/C++?!?!
Přispěvatel: Jakub Galgonek 12. 04. 2013, 18:34:55
C program je skompilovany pomocou gcc

A s jakými flagy?
Název: Re:C# je rychlejsi ako C/C++?!?!
Přispěvatel: Logik 12. 04. 2013, 18:37:02
JIT compilátor opravdu může bejt v některejch případech rychlejší. Ale tady bych spíš
čekal, že v jednom případě byl provedenej loop unroling či vektorizace, zatímco
v druhy, případě ne.

Chtělo by to flagy kompilátoru a hodně by pověděl i disassembling.
Název: Re:C# je rychlejsi ako C/C++?!?!
Přispěvatel: Program 12. 04. 2013, 18:37:29
Podobným způsobem jsem si svýho času hrál, jen ne s C#, ale s Javou. Taky jsem se divil, že byla Java výrazně rychlejší, pak jsem zjistil, že jsem opomněl alespoň -O2 u gcc. Tím se C dostalo mírně před Javu.
Název: Re:C# je rychlejsi ako C/C++?!?!
Přispěvatel: Michal Štrba 12. 04. 2013, 18:37:56
C program je skompilovany pomocou gcc

A s jakými flagy?

So ziadnymi. Teraz som to vyskusal skompilovat s -std=c99 ale vysledok je uplne rovnaky.
Název: Re:C# je rychlejsi ako C/C++?!?!
Přispěvatel: DK 12. 04. 2013, 18:38:26
tak to zkompiluj s -O3 :)
Název: Re:C# je rychlejsi ako C/C++?!?!
Přispěvatel: Michal Štrba 12. 04. 2013, 18:40:33
tak to zkompiluj s -O3 :)
Tak s -O3 to uz facha na 0.003 :D sa vykon fakt zlepsil.
Název: Re:C# je rychlejsi ako C/C++?!?!
Přispěvatel: Vladimír 12. 04. 2013, 18:41:42
Jak bylo řečeno výše, zdroják nestačí. Je nutné vědět,
co s tím provedl překladač v assembleru.
Název: Re:C# je rychlejsi ako C/C++?!?!
Přispěvatel: Michal Štrba 12. 04. 2013, 18:44:41
tak to zkompiluj s -O3 :)
Tak s -O3 to uz facha na 0.003 :D sa vykon fakt zlepsil.
ale inac nebude to tym, ze s -O3 kompilator spravi take veci, ze uplne vynecha dany cyklus a dosadi do n rovno tu hodnotu, ktoru bude mat jasne na konci cyklu?
Název: Re:C# je rychlejsi ako C/C++?!?!
Přispěvatel: Jakub Galgonek 12. 04. 2013, 18:49:03
ale inac nebude to tym, ze s -O3 kompilator spravi take veci, ze uplne vynecha dany cyklus a dosadi do n rovno tu hodnotu, ktoru bude mat jasne na konci cyklu?

O tom silně pochybuji. Ale koukni se na výsledný kód v assembleru (pomocí -S) a z něj to poznáš.
Název: Re:C# je rychlejsi ako C/C++?!?!
Přispěvatel: Jakub Galgonek 12. 04. 2013, 18:54:33
ale inac nebude to tym, ze s -O3 kompilator spravi take veci, ze uplne vynecha dany cyklus a dosadi do n rovno tu hodnotu, ktoru bude mat jasne na konci cyklu?

O tom silně pochybuji. Ale koukni se na výsledný kód v assembleru (pomocí -S) a z něj to poznáš.

No jo, nemazlí se s tím, prostě to n vyhodí úplně :D
Název: Re:C# je rychlejsi ako C/C++?!?!
Přispěvatel: Michal Štrba 12. 04. 2013, 18:54:43
Kedze assembler neovladam, davam vam tu tie kody:

bez -O3

   .file   "test.c"
   .text
   .globl   main
   .type   main, @function
main:
.LFB0:
   .cfi_startproc
   pushq   %rbp
   .cfi_def_cfa_offset 16
   .cfi_offset 6, -16
   movq   %rsp, %rbp
   .cfi_def_cfa_register 6
   movl   $0, -8(%rbp)
   movl   $0, -4(%rbp)
   jmp   .L2
.L3:
   addl   $1, -8(%rbp)
   addl   $1, -4(%rbp)
.L2:
   cmpl   $999999998, -4(%rbp)
   jle   .L3
   movl   $0, %eax
   popq   %rbp
   .cfi_def_cfa 7, 8
   ret
   .cfi_endproc
.LFE0:
   .size   main, .-main
   .ident   "GCC: (Ubuntu/Linaro 4.7.2-23ubuntu2) 4.7.3"
   .section   .note.GNU-stack,"",@progbits


s -O3 (super rychle)

   .file   "test.c"
   .section   .text.startup,"ax",@progbits
   .p2align 4,,15
   .globl   main
   .type   main, @function
main:
.LFB0:
   .cfi_startproc
   xorl   %eax, %eax
   ret
   .cfi_endproc
.LFE0:
   .size   main, .-main
   .ident   "GCC: (Ubuntu/Linaro 4.7.2-23ubuntu2) 4.7.3"
   .section   .note.GNU-stack,"",@progbits
Název: Re:C# je rychlejsi ako C/C++?!?!
Přispěvatel: Michal Štrba 12. 04. 2013, 18:58:07
Ale podla mna je spravne porovnavat bez akychkolvek -O, pretoze vtedy kompilator C urobi len nejake vychytraciny (cheatuje :D) zatial co C# to musi vsetko spravit poctivo. Takze zatial za pravoplatne porovnanie povazujem to z mojho prveho prispevku.
Název: Re:C# je rychlejsi ako C/C++?!?!
Přispěvatel: Jakub Galgonek 12. 04. 2013, 18:58:59
Kedze assembler neovladam, davam vam tu tie kody:

V prvním případě se normálně skáče (vykonává se for-cyklus) v druhém případě se nedělá nic (krom nastavení návratové hodnoty).
Název: Re:C# je rychlejsi ako C/C++?!?!
Přispěvatel: Jakub Galgonek 12. 04. 2013, 19:01:07
Ale podla mna je spravne porovnavat bez akychkolvek -O, pretoze vtedy kompilator C urobi len nejake vychytraciny (cheatuje :D) zatial co C# to musi vsetko spravit poctivo. Takze zatial za pravoplatne porovnanie povazujem to z mojho prveho prispevku.

To je hloupost, kompilátor C# také jistě provádí optimalizace, takže je dost možné, že ani on ten cyklus vlastně vůbec neprovádí  :)
Název: Re:C# je rychlejsi ako C/C++?!?!
Přispěvatel: Michal Štrba 12. 04. 2013, 19:08:22
Ale podla mna je spravne porovnavat bez akychkolvek -O, pretoze vtedy kompilator C urobi len nejake vychytraciny (cheatuje :D) zatial co C# to musi vsetko spravit poctivo. Takze zatial za pravoplatne porovnanie povazujem to z mojho prveho prispevku.

To je hloupost, kompilátor C# také jistě provádí optimalizace, takže je dost možné, že ani on ten cyklus vlastně vůbec neprovádí  :)
Nicnerobenie by mu urcite netrvalo skoro sekundu. Skusim sa nejako dopracovat aj k skompilovanemu C# kodu a uvidime co robi.
Název: Re:C# je rychlejsi ako C/C++?!?!
Přispěvatel: Jakub Galgonek 12. 04. 2013, 19:13:34
Nicnerobenie by mu urcite netrvalo skoro sekundu.

Musí přece nainicializovat tu svou virtuální mašinu, ne?

Můžeš si udělat test. Pokud se ten cyklus opravdu provádí, tak by se doba běhu měla měnit s počtem iterací cyklu (měla by to být přibližně afinní funkce). Co když těch iterací bude 2*999999999?
Název: Re:C# je rychlejsi ako C/C++?!?!
Přispěvatel: Michal Štrba 12. 04. 2013, 19:18:03
Nicnerobenie by mu urcite netrvalo skoro sekundu.

Musí přece nainicializovat tu svou virtuální mašinu, ne?

Můžeš si udělat test. Pokud se ten cyklus opravdu provádí, tak by se doba běhu měla měnit s počtem iterací cyklu (měla by to být přibližně afinní funkce). Co když těch iterací bude 2*999999999?

Ked je iteraci 2x viac tak aj cas behu je priblizne 2x vacsi:

real   0m1.884s
user   0m1.872s
sys   0m0.012s


mimochodom, tu je podstatna cas CIL kodu C# programu (tomu sa uz vobec nerozumiem :D)


   .entrypoint
   // Code size 29 (0x1d)
   .maxstack 3
   .locals init (
      int32   V_0,
      int32   V_1)
   IL_0000:  ldc.i4.0
   IL_0001:  stloc.0
   IL_0002:  ldc.i4.0
   IL_0003:  stloc.1
   IL_0004:  br IL_0011

   IL_0009:  ldloc.0
   IL_000a:  ldc.i4.1
   IL_000b:  add
   IL_000c:  stloc.0
   IL_000d:  ldloc.1
   IL_000e:  ldc.i4.1
   IL_000f:  add
   IL_0010:  stloc.1
   IL_0011:  ldloc.1
   IL_0012:  ldc.i4 999999999
   IL_0017:  blt IL_0009

   IL_001c:  ret
    } // end of method Program::Main
Název: Re:C# je rychlejsi ako C/C++?!?!
Přispěvatel: Jakub Galgonek 12. 04. 2013, 19:35:39
mimochodom, tu je podstatna cas CIL kodu C# programu

CIL neznám, ale soudě podle toho řádku s blt ten kód cyklus opravdu provádí. Koukal jsem znovu na výstup z assembleru u C varianty, když není zapnutá optimalizace. Problém je tam ten, že kód provádí ty aritmetické operace s operandy v paměti a ne v registrech - což je časově náročnější. Zapnutí optimalizací však nemůžeš považovat za podvádění, spíše naopak - měl by jsi porovnávat dobu běhu plně optimalizovaného kódu.
Název: Re:C# je rychlejsi ako C/C++?!?!
Přispěvatel: Jakub Galgonek 12. 04. 2013, 19:45:35
Schválně si zkus ještě přeložit a pustit tohle:

Kód: [Vybrat]
int main() {
  register int n = 0;
  for (register int i = 0;  i < 999999999;  i++) {
    n++;
  }
}
Název: Re:C# je rychlejsi ako C/C++?!?!
Přispěvatel: TomasVoracek 12. 04. 2013, 20:03:30
Hned mi to pripomnelo http://blogs.msdn.com/b/ricom/archive/2005/05/19/420158.aspx

Jinak porovnavat vysledky 2 RUZNE nastavenych kompilatoru kdy druhy JASNE musi prohrat je ... nefer  ::)
Ten C# by se dal jeste zrychlit ngenem jen tak na okraj.
Název: Re:C# je rychlejsi ako C/C++?!?!
Přispěvatel: pravdokop 12. 04. 2013, 20:16:48
Musím se vždycky usmívat, když se znovu a znovu objevují příspěvky, že nějaký kompilátor či dokonce interpretr je rychlejší než C/C++.
C/C++ umožňují pracovat s registry a s přímými přístupy do paměti přes pointery. Nic rychlejšího kromě assembleru už prostě nevymyslíte i kdybyste se rozkrájel :-D. Zapnutí optimalizátoru samozřejmě není žádné cheatování ale regulérní metoda, jejíž možnost a přínosnost je naopak ukazatelem vhodnosti toho či onoho jazyka pro rychlý běh aplikací.
Název: Re:C# je rychlejsi ako C/C++?!?!
Přispěvatel: Michal Štrba 12. 04. 2013, 20:24:58
Schválně si zkus ještě přeložit a pustit tohle:

Kód: [Vybrat]
int main() {
  register int n = 0;
  for (register int i = 0;  i < 999999999;  i++) {
    n++;
  }
}

skusim som a je to o kusticek rychlejsie, stale vsak asi 4x pomalsie

real   0m3.059s
user   0m3.036s
sys   0m0.004s
Název: Re:C# je rychlejsi ako C/C++?!?!
Přispěvatel: Michal Štrba 12. 04. 2013, 20:27:51
Zapnutí optimalizátoru samozřejmě není žádné cheatování ale regulérní metoda, jejíž možnost a přínosnost je naopak ukazatelem vhodnosti toho či onoho jazyka pro rychlý běh aplikací.

Ano, zapnutie optimalizatora v tomto pripade je skutocne cheatovanie, pretoze ucel testu je porovnat KTORY PROGRAM VYKONA DANY CYKLUS RYCHLEJSIE. Kedze optimalizator dany cyklus ODSTRANI, je test uplne na prd. V inom pripade, ked by cyklus mal skutocny zmysel by sa to nedalo takto osalit.
Preto stale za jediny spravny test povazujem test bez optimalizacie, v ktorom je C# 4-5x rychlejsi ako C (aj s pouzitim registrov).
Název: Re:C# je rychlejsi ako C/C++?!?!
Přispěvatel: Jakub Galgonek 12. 04. 2013, 20:29:49
C/C++ umožňují pracovat s registry a s přímými přístupy do paměti přes pointery. Nic rychlejšího kromě assembleru už prostě nevymyslíte i kdybyste se rozkrájel :-D. Zapnutí optimalizátoru samozřejmě není žádné cheatování ale regulérní metoda

Jen tak na okraj, čím větší vám jazyk dá svobodu, tím menší prostor má optimalizátor. Třeba potřebujete obsah celočíselné proměnné x a tak si ji načtete do registru. Pak přes ukazatel na double zapíšete někam do paměti. A teď chcete znovu použít proměnnou x. Musí ji překladač nechat znovu načíst z paměti anebo stačí použít hodnotu v registru? Ne, že bych neznal odpověď, ale co myslíte :-)?
Název: Re:C# je rychlejsi ako C/C++?!?!
Přispěvatel: Jakub Galgonek 12. 04. 2013, 20:30:59
skusim som a je to o kusticek rychlejsie, stale vsak asi 4x pomalsie

Pořád to neoptimalizuje, jen to už alespoň cpe do registrů.
Název: Re:C# je rychlejsi ako C/C++?!?!
Přispěvatel: Jakub Galgonek 12. 04. 2013, 20:36:26
Preto stale za jediny spravny test povazujem test bez optimalizacie, v ktorom je C# 4-5x rychlejsi ako C (aj s pouzitim registrov).

A kde bereš tu jistotu, že ten překladač C# také neoptimalizuje? Ano, vykoná ten cyklus, ale je to bez optimalizace? V podstatě testuješ, který překladač je dostatečně blbý, aby ten cyklus vykonával :). Mimochodem, u gcc se většinou považuje za "normální" překládat s -O2.
Název: Re:C# je rychlejsi ako C/C++?!?!
Přispěvatel: OMG 12. 04. 2013, 21:03:51
Musím se vždycky usmívat, když se znovu a znovu objevují příspěvky, že nějaký kompilátor či dokonce interpretr je rychlejší než C/C++.
C/C++ umožňují pracovat s registry a s přímými přístupy do paměti přes pointery. Nic rychlejšího kromě assembleru už prostě nevymyslíte i kdybyste se rozkrájel :-D. Zapnutí optimalizátoru samozřejmě není žádné cheatování ale regulérní metoda, jejíž možnost a přínosnost je naopak ukazatelem vhodnosti toho či onoho jazyka pro rychlý běh aplikací.

Musím se vždycky usmívat, jak mají někteří lidé zafixováno, že nejrychlejší je assembler a C je skoro tak rychlé jako assembler a všechno ostatní je pomalejší.
A když to platí, tak to přece musí platit i u tak malého kousíčku kódu, jako je jeden for cyklus.

Pokud máme program který je celý tvořen pouze for cyklem ve kterém je pouhá jedna inkrementace celočíselné proměnné, tak neporovnáváte rychlost jazyka jako takového, ale porovnáváte pouze kompilátory a jejich nastavení. U takovéhoto kódu prostě záleží, jestli tam ty kompilátory nechají cyklus. Pokud by ho tam nechaly - pak je docela možné, že GCC i CLR JIT kompilátor vyplivnou stejné instrukce - a pokud pomineme CLR režii, tak budou oba programy limitně stejně rychlé.
A je jasné, že v reálném světě u reálných dlouhých cyklů asi nebude mít kompilátor možnost je vyhodit a nahradit pouhým přiřazením proměnné.

Anebo se bude optimalizovat protože to v daném případě půjde. Což CLR dělá zřejmě automaticky (osobně nevím jak moc optimalizuje Mono CLR) a u GCC je to potřeba holt zapnout flagem.


Tipuji, že kdybych založil vlákno "C/C++ je rychlejsi ako C/C++" a rozebíralo se tam rozdíl rychlosti kódů (běžícíh pod windows) zkompilovaného
-na C/C++ kompilátoru od intelu a
-na C/C++ kompilátoru od microsoftu,
že by ty časové rozdíly (a hraní s parametry) byly dost podobné :-D

Název: Re:C# je rychlejsi ako C/C++?!?!
Přispěvatel: gamer 12. 04. 2013, 21:50:28
Třeba potřebujete obsah celočíselné proměnné x a tak si ji načtete do registru. Pak přes ukazatel na double zapíšete někam do paměti. A teď chcete znovu použít proměnnou x. Musí ji překladač nechat znovu načíst z paměti anebo stačí použít hodnotu v registru?
Tohle odporuje strict aliasing rules a gcc -O2 optimalizuje na strict aliasing. Naštěstí je gcc takovou prasárnu schopno poznat a (většinou) řekne warning.
Název: Re:C# je rychlejsi ako C/C++?!?!
Přispěvatel: Jakub Galgonek 12. 04. 2013, 22:03:55
Tohle odporuje strict aliasing rules

Ale strict aliasing je v C až od verze C99, ne? Prostě se přidalo omezení v tom, co může programátor dělat, aby se mohlo lépe optimalizovat. To jen tak na okraj k té poznámce C vs. assembler, co tu zazněla.
Název: Re:C# je rychlejsi ako C/C++?!?!
Přispěvatel: gamer 12. 04. 2013, 22:12:57
Ale strict aliasing je v C až od verze C99, ne? Prostě se přidalo omezení v tom, co může programátor dělat, aby se mohlo lépe optimalizovat. To jen tak na okraj k té poznámce C vs. assembler, co tu zazněla.
Je to až od C99, což je ale už poměrně stará verze. gcc -O2 s tím počítá a kód který nedodržuje strict aliasing nefunguje, nicméně většina lidí to neví.
Název: Re:C# je rychlejsi ako C/C++?!?!
Přispěvatel: prezek 12. 04. 2013, 22:29:30
Zkus do zdrojáku přidat volatile (volatile int n = 0;) a pak to C přeložit s optimalizací. Tím by se mělo zabránit kompilátoru, aby zahodil celý cyklus, Jinak se to moc porovnávat nedá.
Název: Re:C# je rychlejsi ako C/C++?!?!
Přispěvatel: Jakub Galgonek 12. 04. 2013, 22:35:00
Zkus do zdrojáku přidat volatile (volatile int n = 0;) a pak to C přeložit s optimalizací. Tím by se mělo zabránit kompilátoru, aby zahodil celý cyklus, Jinak se to moc porovnávat nedá.

Když zapne volatile, tak se bude n neustále synchronizovat s pamětí - v každé iteraci se přečte aktuální hodnota n z paměti, přičte se jedna a výsledek se zase zapíše do paměti. Tím to totálně pohřbí.
Název: Re:C# je rychlejsi ako C/C++?!?!
Přispěvatel: prezek 12. 04. 2013, 22:48:21
může dát volatile do C i C#, nebo ne? Já nemám možnost C# vyzkoušet, ale k nějakému zrychlení C připsáním volatile a optimalizací došlo. Ještě lepší výsledek má ale:
Kód: [Vybrat]
int main() {
  int n = 0;
  for (int i = 0;  i < 999999999;  i++) {
  __asm("nop");
    n++;
  }
}
u mě vychází zhruba poloviční čas s optimalizací -O2 oproti původnímu zdrojáku bez optimalizace.
Název: Re:C# je rychlejsi ako C/C++?!?!
Přispěvatel: Jakub Galgonek 12. 04. 2013, 23:02:39
u mě vychází zhruba poloviční čas s optimalizací -O2 oproti původnímu zdrojáku bez optimalizace.

Ono je hlavně to, o co se tazatel pokouší, docela kravina. Porovnávat dobu běhu, ale házet optimalizátoru klacky pod nohy je na nic.
Název: Re:C# je rychlejsi ako C/C++?!?!
Přispěvatel: Ivorne 12. 04. 2013, 23:12:22
Úplně nesmyslné téma. Chtěl bych rozepsat proč, ale to fakt nemá cenu. Sry za zbytečný příspěvek, něco jsem napsat fakt musel
Název: Re:C# je rychlejsi ako C/C++?!?!
Přispěvatel: pravdokop 12. 04. 2013, 23:48:38
Ano, zapnutie optimalizatora v tomto pripade je skutocne cheatovanie, pretoze ucel testu je porovnat KTORY PROGRAM VYKONA DANY CYKLUS RYCHLEJSIE. Kedze optimalizator dany cyklus ODSTRANI, je test uplne na prd. V inom pripade, ked by cyklus mal skutocny zmysel by sa to nedalo takto osalit.
Preto stale za jediny spravny test povazujem test bez optimalizacie, v ktorom je C# 4-5x rychlejsi ako C (aj s pouzitim registrov).

A to jste právě vedle! Prázdný test nikoho nezajímá, snad jen reklamní panáky. O co jde, je rychlost reálných programů, které mají pro reálné uživatele skutečný význam. A tam zvítězí ten, kdo optimalizuje a je proto rychlejší. Ale pokud chcete být úmyslně pomalejší, pak samozřejmě "necheatujte"! :-))))

Mimochodem, i kdybyste nastavil optimalizaci běžného kompilátoru C/C++ o stupeň níže tak, aby cyklus rovnou nevyhodil, tak dosáhnete rychlosti, kterou už žádný jiný jazyk Z PRINCIPU nepřekoná. Prostě proto, že při kvalitě dnešních C/C++ překladačů byste jej většinou nepřekonal ani assemblerem. Zkuste si  disassemblovat nějaký jednoduchý kód, vygenerovaný např. gcc při O3 a zkuste jej ručně urychlit! Téměř jistě se Vám to nepovede.
Název: Re:C# je rychlejší než C/C++?
Přispěvatel: Mirek Prýmek 12. 04. 2013, 23:58:50
A já jsem myslel, že tuhle stránku

http://benchmarksgame.alioth.debian.org/u64q/benchmark.php?test=all&lang=csharp&lang2=gpp

zná už úplně každý...

:)
Název: Re:C# je rychlejsi ako C/C++?!?!
Přispěvatel: pravdokop 13. 04. 2013, 00:09:06

Musím se vždycky usmívat, jak mají někteří lidé zafixováno, že nejrychlejší je assembler a C je skoro tak rychlé jako assembler a všechno ostatní je pomalejší.
A když to platí, tak to přece musí platit i u tak malého kousíčku kódu, jako je jeden for cyklus.

Pokud máme program který je celý tvořen pouze for cyklem ve kterém je pouhá jedna inkrementace celočíselné proměnné, tak neporovnáváte rychlost jazyka jako takového, ale porovnáváte pouze kompilátory a jejich nastavení. U takovéhoto kódu prostě záleží, jestli tam ty kompilátory nechají cyklus. Pokud by ho tam nechaly - pak je docela možné, že GCC i CLR JIT kompilátor vyplivnou stejné instrukce - a pokud pomineme CLR režii, tak budou oba programy limitně stejně rychlé.


Dobýváte se do otevřených dveří... Řekl jsem v podstatě totéž co Vy: Že nic RYCHLEJŠÍHO nevymyslíte. NE, že všichni ostatní musí být POMALEJŠÍ!
Název: Re:C# je rychlejší než C/C++?
Přispěvatel: Trident 13. 04. 2013, 01:25:41
To je vsechno moc super co tu pisete, ale nemaje vysokych skol ni programatorskych party (a tudis se plazim pred vama kanalama), tak mi tu v komentarich schazi:
1. Otazka v subjectu zni jestli je jazyk x rychlejsi nez y. Vzapeti tazatel uvadi konkretni compilery/interprety. Oddelme prosim jazyk a implementaci compileru/interpretu.

2. Nikdo z vas tu nezminil paralelismus a optimalizaci interprety kodu na vic svabiku.

3. Kdyz uz jsme u gcc. Prectete si:http://sunsite.ualberta.ca/Documentation/Gnu/gcc-2.95.2/html_chapter/gcc_toc.html#TOC98
A to odstavec 5-7. To co jsem cetl cca pred 10ti lety stale plati. gcc neni uplnej blbecek ani pri -O0. Prestanme predpokladat chovani jako u starych kompileru co byly jen hloupe prepisovace kodu.

4. Proc lidi ztracej cas tim aby dokazali ze compiler prechytraci? A zrovna v dnesni dobe kdy si nektere compilery pomalu uvedomuji samy sebe:) Pokud danou konstrukci lepe zmakne kod v asembleru tak ho delam v asembleru. Pokud Ccko tak pouzivam Ccko. Vzdyt se to da sesroubovat dohromady. Ze to tomu jankovi nepujde na vice platformach to uz je jina vec. Tim se musi vytrestat sam. Jinac se to nenauci.
Název: Re:C# je rychlejší než C/C++?
Přispěvatel: pravdokop 13. 04. 2013, 01:52:53
Nedalo mi to, a otestoval jsem si testovací program na svém kompu běžným linuxovým g++ kompilerem (bez jakýchkoliv úprav typu vložení klíčových slov "registry" apod.):

Bez optimalizace, tj. s g++ -O0:  time = 3,225 s
S nejnižší optimalizací, tj. s g++ -O1:  time = 0,564 s
S vyšší optimalizací, tj. s g++ -O2:  time = 0,003 s

Je zde krásně vidět, že již základní optimalizce "urychlí" C++ program cca 6x, čímž se minimálně vyrovná C#. Ještě lepší optimalizace vyhodí (naprosto správně) celou smyčku pryč jakožto zbytečnou.
Dále je z disassembleru vidět, že další urychlení je prakticky nemožné, celá smyčka jsou pouhé dvě instrukce (dekrementace registru a podmíněný skok při nenule s blízkým offsetem):

000000000040072d:   sub $0x1,%eax
0000000000400730:   jne 0x40072d <main+9>

Nejde o nic jiného, než že zjevně C# kompiler optimalizuje tento program podobně jako g++ s volbou O1. Možná je tak nastaven defaultně, možná ne, to je celkem jedno. Moje teze, že "nic" není rychlejší než C/C++ tímto pokusem zůstala nezpochybněna. Naopak doměnka, že C# je rychlejší, byla tímto vyvrácena.
Název: Re:C# je rychlejsi ako C/C++?!?!
Přispěvatel: student 13. 04. 2013, 01:58:04
Mimochodem, i kdybyste nastavil optimalizaci běžného kompilátoru C/C++ o stupeň níže tak, aby cyklus rovnou nevyhodil, tak dosáhnete rychlosti, kterou už žádný jiný jazyk Z PRINCIPU nepřekoná. Prostě proto, že při kvalitě dnešních C/C++ překladačů byste jej většinou nepřekonal ani assemblerem. Zkuste si  disassemblovat nějaký jednoduchý kód, vygenerovaný např. gcc při O3 a zkuste jej ručně urychlit! Téměř jistě se Vám to nepovede.
To zalezi hlavne od urovne toho kodu. Ak ludia nepouzivaju restrict u pointerov, pouzivaju signed datove typy, volatile atd, tak tam sa da nahnat par instrukcii.

Inak o neprekonani "Z PRINCIPU" to nemusi byt az tak uplne pravda, hlavne pre "exoticke" pripady. Ak ma napriklad Java ovela viac pamati ako C, tak casto dokaze jej GC pracovat lepsie ako malloc / free uz po dokonceni JIT kompilacie (na to treba nieco ako 10k priechodov cez 1 miesto).
Název: Re:C# je rychlejsi ako C/C++?!?!
Přispěvatel: pravdokop 13. 04. 2013, 02:08:11

To zalezi hlavne od urovne toho kodu. Ak ludia nepouzivaju restrict u pointerov, pouzivaju signed datove typy, volatile atd, tak tam sa da nahnat par instrukcii.

Inak o neprekonani "Z PRINCIPU" to nemusi byt az tak uplne pravda, hlavne pre "exoticke" pripady. Ak ma napriklad Java ovela viac pamati ako C, tak casto dokaze jej GC pracovat lepsie ako malloc / free uz po dokonceni JIT kompilacie (na to treba nieco ako 10k priechodov cez 1 miesto).

Jasně, určitě se dají najít exotické případy, které člověk vyřeší lépe než sebelepší AI. Ale vyjímka, jak známo, potvrzuje pravidlo.  :D
Název: Re:C# je rychlejsi ako C/C++?!?!
Přispěvatel: Ivan 13. 04. 2013, 18:25:39
Jasně, určitě se dají najít exotické případy, které člověk vyřeší lépe než sebelepší AI.

Nekdy ty pripady nemusi byt ani nijak exoticke. Jave lezi vsechny objekty na heapu a promenne jsou jen reference na ne - zadna jina moznost neexistuje. Zamco v C++ existuje spousta moznosti. Nedavno jsem neco podobneho resil v jednom OS projektu v QTcku. V QTcku maji objekty tzv. thread-affinity kazdy objekt patri k nejakemu vlaknu a v kontextu toho vlakna prijima signaly a v kontextu toho vlakna taky musi byt znicen. To pridavalo tolik problemu s race-conditions v MVC ze se nakonec vsechno predavalo hodnotou a QStringy(a jiny QObjekty) se porad dokola kopirovaly. Nakonec ten kod byl pomalejsi nez byt byl v Jave. Popravde receno neexistuje zadny realny duvod proc by melo byt C++ obecne vyrazne rychlejsi nez Java.

PS: pokud by to nekoho zajimalo tak muzu dodat dva identicke parsery SQL vygenerovane pomoci ANTLR. Ten Javovy je 2x rychlejsi nez ten v C++, zatim jsem neprisel na duvod proc tmu tak je.
Název: Re:C# je rychlejsi ako C/C++?!?!
Přispěvatel: x86 13. 04. 2013, 18:35:44
Popravde receno neexistuje zadny realny duvod proc by melo byt C++ obecne vyrazne rychlejsi nez Java.
Popravdě řečeno, jedním z důvodů je např. (duplicitní) softwarová snaha JVM o to, co už v moderním procesoru způsobuje na hardwarové úrovni Branch Target Buffer. Ale to si chce místo siláckých řečí přečíst a pochopit alespoň manuály od Intelu. Dalším důvodem je to, že C++ nutí programátora daleko víc přemýšlet o kódu, který píše, už jen proto, že narozdíl od Javy musí nějak uvolňovat paměť.
Název: Re:C# je rychlejší než C/C++?
Přispěvatel: x14 13. 04. 2013, 22:52:18
Čistě řečnická otázka: je C napsané v C#, nebo je C# napsaný v C?  :)
Název: Re:C# je rychlejší než C/C++?
Přispěvatel: andy 13. 04. 2013, 23:08:01
Tipnul  bych si, že C je napsané v C a C# je napsaný v C# (VM asi bude v C++)....
Název: Re:C# je rychlejší než C/C++?
Přispěvatel: ferren 14. 04. 2013, 00:54:39
kdyby nekiho tady napadlo pridat jeden radek s printfem, aby se iterace musela vykonat, ubylo by 50% prispevku o optimalizacich;-)
Název: Re:C# je rychlejší než C/C++?
Přispěvatel: Jakub Galgonek 14. 04. 2013, 01:08:53
kdyby nekiho tady napadlo pridat jeden radek s printfem, aby se iterace musela vykonat, ubylo by 50% prispevku o optimalizacich;-)

Pak by ale ten experiment nebyl skoro vůbec o překladačích jako spíše o implementaci IO :-)
Název: Re:C# je rychlejší než C/C++?
Přispěvatel: Pupi 14. 04. 2013, 21:15:43
C/C++ je urcite rychlejsie nez C#. Preto sa C/C++ pouziva v roznych odvetviach kde je potreba rychleho spracovania a rychlej odozvy. Moze byt pripad, ze v niecom C# predbieha C/C++ alebo obecne vzate je rychlejsi C/C++
Název: Re:C# je rychlejší než C/C++?
Přispěvatel: nemo 14. 04. 2013, 23:26:49
Mimochodom tiez sa tu nespomina ze aj ten c# VM , okrem jeho kompileru, robi nejaku JIT optimalizaciu. Takze v case sa moze spustena aplikacia pod c# teoreticky zrychlovat. Na druhu stranu ak je povedzme pametovo narocna, hlavne v castej alokacii, tak potom moze dost neprijemne do vykonu zasiahnut GC. Proste pri takejto jednoduchej ukazke kodu je to uplne zbytocna polemika.
A mimochodom c# alebo aj java sa nepouzivaju alebo nepresadili hlavne koli svojmu vykonu/nevykonu. Dovod preco vznikly a pouzivaju sa je hlavne bezpecnejsi kod a rychlejsi development a teda aj vyssiu produktiviu. Dan za to moze byt prave vykon, pametova narocnost a aj silna zavyslost na VM.
Název: Re:C# je rychlejší než C/C++?
Přispěvatel: DK 15. 04. 2013, 07:27:23
nemo: java ze se nepouziva? dovolim si tvrdit opak :) ono tim, ze to bezi ve VM je to sice pametove narocnejsi, nez c/c++, ale vzhledem k dlouhodobejsi cene pameti je to uz uplne jedno

a prave ta java se na serverove casti pouziva hodne casto (zatimco c# se pouziva prevazne pouze pro desktopove windows aplikace)
Název: Re:C# je rychlejší než C/C++?
Přispěvatel: JSH 15. 04. 2013, 09:03:54
nemo: java ze se nepouziva? dovolim si tvrdit opak :) ono tim, ze to bezi ve VM je to sice pametove narocnejsi, nez c/c++, ale vzhledem k dlouhodobejsi cene pameti je to uz uplne jedno
Myslím, že jsi nepochopil, co nemo napsal. On nepsal, že by se Java a C3 nepoužívaly, ale že se používají z jiného důvodu, než je maximální výkon.
Název: Re:C# je rychlejsi ako C/C++?!?!
Přispěvatel: User 15. 04. 2013, 09:31:10
Jen tak na okraj, čím větší vám jazyk dá svobodu, tím menší prostor má optimalizátor. Třeba potřebujete obsah celočíselné proměnné x a tak si ji načtete do registru. Pak přes ukazatel na double zapíšete někam do paměti. A teď chcete znovu použít proměnnou x. Musí ji překladač nechat znovu načíst z paměti anebo stačí použít hodnotu v registru? Ne, že bych neznal odpověď, ale co myslíte :-)?

Záleží jestli tu hodnotu v paměti mohl změnit jiný thread nebo ne. Různé jazyky toto řeší různě, například Java je navržená tak že pokud programátor explicitně neřekne že se ta paměť z jiného threadu měnit může (volatile nebo synchronizací) tak platí že se měnit nemůže (což programátor musí zaručit znalostí algoritmu - a běda pokud ne, z toho jsou hodně špatné chyby) a tedy hodnotu z registru lze použít.
Název: Re:C# je rychlejsi ako C/C++?!?!
Přispěvatel: Jakub Galgonek 15. 04. 2013, 09:56:54
Jen tak na okraj, čím větší vám jazyk dá svobodu, tím menší prostor má optimalizátor. Třeba potřebujete obsah celočíselné proměnné x a tak si ji načtete do registru. Pak přes ukazatel na double zapíšete někam do paměti. A teď chcete znovu použít proměnnou x. Musí ji překladač nechat znovu načíst z paměti anebo stačí použít hodnotu v registru?

Záleží jestli tu hodnotu v paměti mohl změnit jiný thread nebo ne.

V tomto případě záleží hlavně na tom, zda ten ukazatel na double náhodou neukazuje na oblast paměti, kde leží proměnná x.
Název: Re:C# je rychlejsi ako C/C++?!?!
Přispěvatel: gamer 15. 04. 2013, 10:08:29
paměť z jiného threadu měnit může (volatile nebo synchronizací)
volatile neříká nic o tom, že se pamět může měnit z jiného threadu, ale že se může měnit asynchronně. volatile na sychronizaci mezi thready použít nejde.
http://molecularmusings.wordpress.com/2012/03/05/volatile-thread-synchronization/
Název: Re:C# je rychlejsi ako C/C++?!?!
Přispěvatel: User 15. 04. 2013, 10:32:54
paměť z jiného threadu měnit může (volatile nebo synchronizací)
volatile neříká nic o tom, že se pamět může měnit z jiného threadu, ale že se může měnit asynchronně. volatile na sychronizaci mezi thready použít nejde.
http://molecularmusings.wordpress.com/2012/03/05/volatile-thread-synchronization/

Psal jsem o Javě a tam se od verze 5 volatile už pro synchonizaci mezi thready použít dá.
Název: Re:C# je rychlejsi ako C/C++?!?!
Přispěvatel: User 15. 04. 2013, 10:41:03
Jen tak na okraj, čím větší vám jazyk dá svobodu, tím menší prostor má optimalizátor. Třeba potřebujete obsah celočíselné proměnné x a tak si ji načtete do registru. Pak přes ukazatel na double zapíšete někam do paměti. A teď chcete znovu použít proměnnou x. Musí ji překladač nechat znovu načíst z paměti anebo stačí použít hodnotu v registru?

Záleží jestli tu hodnotu v paměti mohl změnit jiný thread nebo ne.

V tomto případě záleží hlavně na tom, zda ten ukazatel na double náhodou neukazuje na oblast paměti, kde leží proměnná x.

Takovým prasárnám jsem už od doby co programuji v Javě odvyknul, neboť Java (nebo i C#) takové nebezpečné operace s ukazateli naštěstí znemožňuje. Ale i kdyby náhodou ten ukazatel ukazoval na oblast paměti, kde leží proměnná x, platí co to jsem napsal - bacha na thready!
Název: Re:C# je rychlejsi ako C/C++?!?!
Přispěvatel: Jakub Galgonek 15. 04. 2013, 10:55:10
Takovým prasárnám jsem už od doby co programuji v Javě odvyknul

Je to prasárna, ale o to tu nešlo ...
Název: Re:C# je rychlejsi ako C/C++?!?!
Přispěvatel: noef 15. 04. 2013, 10:56:44
Zkuste si  disassemblovat nějaký jednoduchý kód, vygenerovaný např. gcc při O3 a zkuste jej ručně urychlit! Téměř jistě se Vám to nepovede.

spatna argumentace. kdyz OP nedokaze rucne optimalizovat konkretni kod, tak to neznamena, ze to plati obecne.

vim celkem jiste, ze rucne optimalizovany kod je vzdy ten nejrychlejsi. nejaky prekladac na to nikdy mit nebude, protoze "nevi" co ma kod delat. nemuze preskladavat slozitejsi bloky, podminky a cykly tak, ze v zaveru nejsou ekvivaletni se vstupnim kodem v c++, ale delaji to, co se od nich ceka (napr. i uzitim vedlejsich efektu instrukci).

java i c# pro normalni uzivatelske (a casto i servrove) aplikace se nyni pouzivaji imo nejvic. vyvoj v c++ je drazsi - podstatne delsi doba ladeni. casto je levnejsi si poridit lepsi hw, nez platit nasobne vic za sw. a samozrejme optimalizace na urovni assembleru se skoro uz nedelaji. ta narocnost jak na znalosti a zkusenosti programatora, tak na cas (i o nekolik radu vic, nez napr. v c/c++), je nepredstavitelna.

tohle vlakno mi pripomnelo klasiku, The story of Mel: http://www.pbm.com/~lindahl/mel.html (http://www.pbm.com/~lindahl/mel.html)  ;D
Název: Re:C# je rychlejsi ako C/C++?!?!
Přispěvatel: gamer 15. 04. 2013, 11:05:05
Psal jsem o Javě a tam se od verze 5 volatile už pro synchonizaci mezi thready použít dá.

No moc bych tomu nevěřil, měla by tam být memory bariéra, ale zdá se, že to v SUNu nedokážou implementovat správně:
http://stackoverflow.com/questions/10620680/why-volatile-in-java-5-doesnt-synchronize-cached-copies-of-variables-with-main
V Java 5 to zavedli a v Java 7u6 build b14 to opravili, takže to už možná opravdu funguje.
Název: Re:C# je rychlejší než C/C++?
Přispěvatel: Luaan 15. 04. 2013, 11:11:32
No, pro ilustraci přikládám ASM, které ten .NETový prográmek spouští na procesoru (pozor, aplikace se nesmí pustit přímo přes VS, jinak je JIT optimalizace úplně vypnutá; je nutné pustit aplikaci zvlášť a attachnout se k ní z debuggeru až po spuštění).

00000006  xor         eax,eax
{
00000008  inc         esi
00000009  inc         eax
0000000a  cmp         eax,5F5E0FFh
0000000f  jl          00000008
}

Je tu jasně vidět, že ano, .NET skutečně umí používat registry (to je mi překvapení). C++ kompilátor je skutečně odvážnější (například otočil cyklus tak, aby mohl používat jne místo jl), ale skutečně nedochází k ničemu tak tragickému, jako že by se inkrementace integeru prováděla v paměti.

Nutno podotknout, že jsem toto skoušel na MS JIT, nikoliv na Mono. Mono je rozhodně ve spoustě kódu mnohem pomalejší.

A velká část .NETu (včetně C#) je napsána v C#, většina v Simple Managed C (také .NET jazyk) a jen pár kritických míst v C/++ resp. ASM. Mono je napsané v C# celé, a i MS má kompletní C# kompilátor napsaný v C# (Roslyn).

Největší nevýhoda C# je zároveň i v jiných věcech velkou výhodou - a jde o ten JIT kompilátor. To znamená, že záleží na konkrétním JIT kompilátoru jak chytře bude kód optimalizovaný, a navíc musí JIT šetřit optimalizacemi, protože na ně má málo času. Windowsácký MS JIT kompilátor je výborný, Mono je na tom výrazně hůř. Každopádně tam pořád zůstává to kritické - .NET umožňuje napsat 99% aplikace snadno a bezpečně, a pro to 1% výkonově kritického kódu dokáže používat stejné prasárny, jako C/ASM.
Název: Re:C# je rychlejší než C/C++?
Přispěvatel: Jakub Galgonek 15. 04. 2013, 11:22:44
C++ kompilátor je skutečně odvážnější (například otočil cyklus tak, aby mohl používat jne místo jl), ale skutečně nedochází k ničemu tak tragickému, jako že by se inkrementace integeru prováděla v paměti.

Ale jo, gcc s vypnutými optimalizacemi to v paměti dělal:

Kód: [Vybrat]
.L3:
   addl   $1, -8(%rbp)
   addl   $1, -4(%rbp)
.L2:
   cmpl   $999999998, -4(%rbp)
   jle   .L3