Se python viene compilato per il montaggio e in esso è scritto un sistema operativo, esso competerà favorevolmente con C nei benchmark?

5

Ok, ho usato la parola python nella domanda, ma potrebbe benissimo essere indipendente dal linguaggio in quanto: Se un linguaggio X ha un assembly di ottimizzazione del compilatore ottimizzato e un OS è scritto in quel lingua, allora competerà favorevolmente con C in benchmarks?

Questo deriva da due concetti che ho (potrebbe essere sbagliato):

  • Le lingue sono definite da regole grammaticali (sintassi-semantica); essi stessi sono indipendenti dalle prestazioni. Le prestazioni sono una funzione dell'implementazione.
  • C è spesso efficiente perché i più popolari sistemi operativi (OS) sono scritti in esso - in modo limitato wrapping e unwrapping - e viene compilato (in questi giorni) codice assembly ottimizzato.

E, sì, prima che alcuni di noi tirino fuori le pistole, capisco e apprezzo che in certe situazioni alcune lingue possono superare la C, ma in generale C fa meglio della maggior parte delle lingue nella maggior parte delle situazioni.

    
posta check123 20.07.2012 - 19:01
fonte

8 risposte

16

In teoria, per ogni programma idealizzato ci sarà un insieme di istruzioni di assemblaggio che è il modo più efficace per attuare quel programma. In teoria, qualsiasi linguaggio potrebbe potenzialmente essere compilato con queste istruzioni macchina ideali, dato un compilatore abbastanza intelligente.

In pratica, no, non esiste un compilatore che trasformi Python in codice macchina che sia veloce come un programma C ottimizzato che fa la stessa cosa. Inoltre, è improbabile che un simile compilatore possa essere scritto, perché python non ha primitive per cose di basso livello come i puntatori. Per rendere il codice ottimamente veloce, il compilatore dovrebbe capire le intenzioni del codice prima che possa tradurlo in comandi di basso livello, il che è un problema incredibilmente difficile.

Questo non significa che non possa avvicinarsi. Forse.

    
risposta data 20.07.2012 - 19:53
fonte
1

In generale, la maggior parte dei linguaggi a blocchi staticamente strutturati a blocchi si compila in un codice macchina molto simile (la maggior parte delle architetture di macchine fornisce il supporto per concetti HLL come for loops e switch statement). Il problema con Python, come altri hanno notato, è la sua natura dinamica. Ciò significa più controlli di runtime e una libreria di runtime più grande, il che significa esecuzione più lenta, non c'è proprio modo di aggirarlo. Ciò non significa che non sia possibile scrivere un sistema operativo in esso, ma non otterrai mai le prestazioni ottimali che possono essere fornite da linguaggi più semplici come C o FORTRAN.

Ciò che sarebbe interessante vedere sarebbe "sistemi Python", con supporto per i puntatori e possibilmente con alcune restrizioni sulle funzionalità dinamiche del linguaggio per consentire moduli compilati più efficienti. Non conosco abbastanza bene Python per sapere quanto sia fattibile, ma ci sono state cose simili prima.

    
risposta data 20.07.2012 - 20:31
fonte
1

Invece di compilare in assembly, facciamo un approccio più pratico (che esiste).

Ci sono programmi come f2c e p2c che compila fortran e pascal in c. La domanda è quindi "questi compilatori possono scrivere un codice migliore di quello che puoi?" In p2c (ad esempio), è necessario scrivere codice aggiuntivo in C per gestire l'elaborazione della stringa.

Questo si traduce anche nel montaggio. Ogni volta che c'è qualcosa che il linguaggio sta facendo per te, sotto le coperte, c'è il probabile cappuccio che un programmatore con la comprensione delle strutture e degli algoritmi necessari per scrivere scriverebbe un codice più compatto (e più veloce) in C.

(edit)

Consideriamo un linguaggio tipizzato dinamico con stringhe e int, un operatore "+" completamente sovraccarico e un comando di stampa.

var foo = 3;
var bar = "a";
var qux = bar + foo;
print qux;

La versione C di questo programma sarebbe:

#include <stdio.h>
#include <string.h>

int main(int argc, char **argv) {
    int foo = 3;
    char *bar = "a";
    char qux[3];
    sprintf(qux,"%s%d",bar,foo);
    printf("%s",qux);
}

(Sì, so che non è ottimale ed è un esempio forzato) Che compila il seguente assembly sulla mia macchina (gcc -S -O9 foo.c)

    .file   "foo.c"
    .section    .rodata.str1.1,"aMS",@progbits,1
.LC0:
    .string "a"
.LC1:
    .string "%s%d"
.LC2:
    .string "%s"
    .text
    .p2align 4,,15
.globl main
    .type   main, @function
main:
.LFB23:
    .cfi_startproc
    pushq   %rbx
    .cfi_def_cfa_offset 16
    movl    $3, %ecx
    movl    $.LC0, %edx
    movl    $.LC1, %esi
    xorl    %eax, %eax
    subq    $16, %rsp
    .cfi_def_cfa_offset 32
    movq    %rsp, %rdi
    .cfi_offset 3, -16
    call    sprintf
    movq    %rsp, %rsi
    movl    $.LC2, %edi
    xorl    %eax, %eax
    call    printf
    addq    $16, %rsp
    .cfi_def_cfa_offset 16
    popq    %rbx
    .cfi_def_cfa_offset 8
    ret
    .cfi_endproc
.LFE23:
    .size   main, .-main
    .ident  "GCC: (SUSE Linux) 4.5.1 20101208 [gcc-4_5-branch revision 167585]"
    .section    .comment.SUSE.OPTs,"MS",@progbits,1
    .string "Ospwg"
    .section    .note.GNU-stack,"",@progbits

A questo punto, la domanda è: cosa ci vorrebbe per scrivere un compilatore che sarebbe in grado di analizzare il codice dinamico e generare quell'assemblaggio. Mentre potrebbe essere possibile con quel linguaggio estremamente limitato, una volta che si inizia ad aggiungere più complessità al linguaggio, una traduzione in qualcosa più vicino alla macchina richiede sempre più codice per gestire la tipizzazione dinamica o il proprio runtime (l'obiettivo C prende questo approccio ) - in entrambi i casi, sarà più lento di qualcosa scritto in C che non ha bisogno di avere quell'overhead.

Oppure, il compilatore ha analizzato tutti i percorsi di esecuzione del codice (per il linguaggio dinamico) che credo equivalga a risolvere il problema dell'arresto.

    
risposta data 20.07.2012 - 19:18
fonte
0

Ho appena letto un articolo che dice che llvm è progettato per avere un front-end per qualsiasi lingua (es. Python) e ha un ottimizzatore / generatore comune. Quindi potresti scrivere un front-end ... Quindi potrebbe essere più veloce. (ancora più veloce se credi che i numeri di HotSpot possano essere ancora più veloci)

Java è in realtà un buon esempio. Normalmente è un codice byte, ma ci sono diversi modi per compilarlo al codice nativo.

Ciò che potresti incontrare sono i problemi di accesso ai dispositivi, gestione della memoria, interruzioni e simili senza aggiungere alcune aggiunte specifiche del sistema.

Penso che potresti prendere Linux come esempio. C'è un mucchio di codice che è comune tra le piattaforme. Questo potrebbe probabilmente essere scritto in qualsiasi cosa. Ma c'è anche un codice specifico per sistema / dispositivo. Ciò richiederebbe un linguaggio più a livello di sistema. E sì, probabilmente potresti trovare un modo in Python per gestirlo.

    
risposta data 20.07.2012 - 19:22
fonte
0

No, non succederà mai. Anche se hai eseguito una riduzione perfetta da Python a codice macchina, ci sono ancora cose come Python crea tutti gli oggetti nell'heap e tale che deve essere tradotto per il programma da eseguire correttamente che sono più lenti di un programma C ponendo alcuni o molti oggetti nello stack. Inoltre, ci saranno tipi dinamici e ricerche che non possono essere dedotti staticamente, per esempio.

È abbastanza impossibile.

    
risposta data 20.07.2012 - 20:34
fonte
0

Quando usi Python come esempio, stai considerando sia il linguaggio che il suo compilatore / interprete per produrre un sistema operativo? Oppure stai scrivendo un compilatore per convertire il tuo linguaggio di alto livello in opcode bare metal?

Tali linguaggi di alto livello vengono solitamente gestiti nel senso che non gestisci mai la garbage collection, i puntatori, gli indirizzi fisici, ecc. Che rendono difficile (almeno per me) immaginare come produrre un sistema operativo che comunichi direttamente con la macchina .

A meno che non si stia scrivendo un servizio di alto livello che consuma servizi prodotti da qualche livello di astrazione hardware sottostante e un gestore di indirizzi fisici, che suona come un'idea intelligente; avendo un sistema operativo modulare parzialmente scritto in C, parzialmente in R, e il resto in Python

    
risposta data 23.08.2017 - 21:48
fonte
0

Generalmente non penso che un programma Python compilato possa sovraperformare un programma C equivalente (anche se potrebbero esserci alcune situazioni eccezionali). Ma il ragionamento potrebbe non essere quello che ti aspetti.

Riepilogo

  • Non tutti i linguaggi compilati sono uguali per quanto riguarda le prestazioni.

  • Il linguaggio misto tra sistema operativo e applicazione non ha molta importanza.

Ragionamento

Scrivi:

This comes from two conceptions I have (could be wrong):

  • Languages are defined by grammar rules (syntax-semantics); they themselves are independent of performance. Performance is a function of implementation.

  • C is often efficient because the most popular OS(es) are written in it - so limited wrapping and unwrapping - and it compiles to (these days) well optimized assembly code.

Non hai completamente ragione.

Come altri già hanno sottolineato, la natura dinamica di Python implica un sovraccarico nelle istruzioni di assemblaggio / macchina risultanti.

Quindi, per alcuni linguaggi (ad esempio Python o Java), per soddisfare la loro semantica il codice macchina risultante deve includere ulteriori istruzioni generali che non richiedono un linguaggio di livello inferiore come C. Quindi le lingue non sono "indipendenti dalle prestazioni".

Hai menzionato la relazione tra linguaggio dell'applicazione e linguaggio operativo. Ciò riguarda solo l'interfaccia tra il codice dell'applicazione e le chiamate del sistema operativo quando è necessario passare parametri e strutture dati tra l'applicazione e il sistema operativo. Se un realmente concettualmente diverso, potresti riscontrare un rallentamento delle chiamate di sistema a causa delle necessarie conversioni di dati.

Ma fintanto che il tuo programma sta calcolando e non sta eseguendo I / O, non chiama il sistema operativo, quindi non c'è bisogno di convertire nulla, e per la tua applicazione, il sistema operativo è solo una libreria che potresti chiamare quando senti il bisogno di farlo. Il resto del tempo, occupa solo memoria, ma senza risorse CPU.

Quindi perché C è un buon linguaggio per un sistema operativo e Python no?

La ragione per i sistemi operativi basati su C non è quella di supportare al meglio le applicazioni scritte in C, ma perché un sistema operativo deve interagire con l'hardware della macchina a un livello basso, e qui C può fare quasi tutto ciò che l'assembly può fare (es. rappresenta indirizzi assoluti). I concetti di Python non supportano questa vista di basso livello della tua macchina che deve essere gestita da un sistema operativo.

Quindi, per ogni livello del software in generale, dovresti scegliere la lingua appropriata (e assicurarti che possano interagire senza troppi problemi). Per un sistema operativo, C è una buona scelta e per le applicazioni puoi scegliere quello che meglio si adatta alle esigenze dell'applicazione.

E un'ultima affermazione sul rendimento: il 90% dei casi di prestazioni sprecate esiste a causa di algoritmi scadenti o di scarse capacità del programmatore, perdendo facilmente i fattori di 10 o 100 rispetto a una soluzione adeguata, mentre un linguaggio compilato potrebbe perdere un fattore di forse 3 contro C.

    
risposta data 24.08.2017 - 00:43
fonte
-4

C si compila per lavorare, non per assemblare. Se python, o qualsiasi altra lingua, fosse compilato anche con i codici macchina, allora sarebbe altrettanto veloce (dipende anche da quanto bene il compilatore ottimizza, però).

    
risposta data 20.07.2012 - 19:23
fonte

Leggi altre domande sui tag