Tester di stress CPU con codice minimo ...


28

introduzione

Esistono molte utility in grado di creare un carico elevato della CPU per sottoporre a stress test i tuoi processori. Su Microsoft Windows, puoi persino utilizzare la scheda di bordo calculator.exe, inserire un numero grande come 999999999e premere n!più volte per far funzionare le tue CPU nel tempo.

Ma cosa c'è in una soluzione se non l'hai creata tu stesso?

La missione

La tua missione - se scegli di accettarlo - è quella di creare il più piccolo strumento di stress test della CPU sul pianeta.

Dovere…

  1. deve produrre un carico della CPU del 100% fino a quando non viene interrotto
  2. deve accettare un input numerico, che rappresenta il numero di secondi in cui deve essere eseguito lo stress test
  3. deve consentire l'interazione dell'utente (pressione dei tasti, chiusura della finestra del terminale o qualcosa del genere) che dovrebbe consentire a un utente di interrompere lo stress test e / o uscire dal programma
  4. deve essere destinato a Microsoft Windows, Mac OSx e / o Linux.
    (Anche un criceto potrebbe sottolineare un Comodore64 ... quindi, è necessario indirizzare un sistema operativo corrente.)

Non devi…

  1. non devono utilizzare programmi o strumenti di terze parti che sostituiscono la funzionalità prevista.
    (Proporre scorciatoie come system('cpuStressThing.exe')squalifica la tua proposta.)

Potrebbe…

  1. può utilizzare qualsiasi approccio / algoritmo / funzionalità per produrre un carico CPU del 100% previsto
  2. può utilizzare qualsiasi linguaggio di programmazione o di scripting
    (purché consenta la verifica pratica della sua funzionalità eseguendolo)

Condizioni vincenti

Presenta il codice sorgente più piccolo possibile. Il vincitore è quello che presenta il codice sorgente più minimale (in termini di dimensioni) che soddisfa le condizioni "must" e "must" di cui sopra. Ora fai bruciare quel bambino ...


MODIFICARE

Poiché la domanda è emersa nell'area dei commenti ... devi solo scegliere come target 1 core della CPU. Non mi aspetto sicuramente che tu produca una soluzione multi-core. Dopotutto, dovrebbe essere divertente, non funziona.


5
"100% di un core" è sufficiente o intendi "100% di una CPU multi-core"?
Tobia,

@Tobia Sì, 1 core è sufficiente. Ho modificato la mia domanda per includere specificamente tali informazioni. Grazie per avermi indicato il fatto che non era tutto troppo chiaro.
e-sushi,

3
i minatori di criptovaluta contano /
TheDoctor,

2
@TheDoctor Se riesci a soddisfare le condizioni che ho descritto ... sii mio ospite. Sarebbe sicuramente interessante vedere un minatore di criptovaluta in grado di battere (ad esempio) uno script bash a 36 byte in dimensione file.
e-sushi,

Il problema è che la maggior parte dei minatori sono diverse migliaia di righe di codice.
TheDoctor,

Risposte:


28

Utilità di base e standard, 36 31 22 29 28 26 byte

yes :|sh&sleep $1;kill $!

2
Sembra davvero stupendo per un codice Bash! Questa è davvero una bella risposta!
Ismael Miguel,

Non hai bisogno di :dentro do :; done. Ho scoperto che do;donefa il lavoro - che ti porterà in 2 byte. Inoltre +1 per essere quasi la metà della mia soluzione bash (l'ho reso eccessivamente complicato senza una buona ragione perché mi ero dimenticato $!).
Chris J,

1
@ChrisJ - che non funziona per me: bash: syntax error near unexpected token `;'. Ho provato queste versioni bash: 3.00.15(1)-release (x86_64-redhat-linux-gnu), 3.2.48(1)-release (x86_64-apple-darwin12),4.2.25(1)-release (x86_64-pc-linux-gnu)
Digital Trauma

1
@ChrisJ - Immagino che tu abbia una kshrisposta a 34 byte allora ;-)
Digital Trauma

2
Lo metterei $1al posto di 10lì, solo per trasformarlo in uno script che "accetta input numerici".
Tobia,

20

Bash / iputils (Linux), 14 byte

ping6 -fw$1 ::

Esegue il ping di inoltro dell'indirizzo nullo IPv6, fino alla scadenza del timer della scadenza -w

avvertenza: consuma solo il 55-60% di CPU sulla mia macchina virtuale di prova

Modifica: - Ritiro il mio avvertimento. Mentre topsegnala che il ping6processo consuma solo il 55-60% di CPU, vedo la percentuale di inattività totale della CPU (2 core VM) avvicinarsi a zero. Questo presumibilmente è perché una buona parte dell'elaborazione sta avvenendo nel kernel mentre gestisce i pacchetti.

Nota: deve essere eseguito come root. Come commenta @Tobia, questo sembra un requisito ragionevole per qualcosa che porterebbe alla CPU. E l'OP lo ha approvato nei commenti.


6
+1. Vorrei rimuovere sudo e dichiarare semplicemente che il test deve essere eseguito come root. Sembra un requisito ragionevole per qualcosa che porge la CPU.
Tobia,

@Tobia - grazie - Penso che ti piaccia qualcosa ;-)
Digital Trauma,

ping -6 :: -t-> solo se questo su Windows ha reso la mia CPU impazzita ... È solo l'equivalente di Linux su Windows, che dà solo errori e non carica nemmeno la CPU all'1%! Sto usando Windows 8 Pro x64 su un core2quad 2.63GHz.
Ismael Miguel,

@IsmaelMiguel - sì - Non ho finestre a portata di mano per testarlo. Ecco perché ho dichiarato "Linux" nel titolo ;-)
Digital Trauma,

Lo so, sto solo "dando" questa risposta come non funzionante, per coloro che stanno pensando di provare lo stesso in Windows, come ho fatto e fallito.
Ismael Miguel,

9

Binario autonomo Elf32 - 86 byte

Scommetto che questo è il più piccolo binario formato Elfo correttamente formato che può essere creato per eseguire questa funzione. Questo verrà eseguito senza alcun supporto aggiuntivo su qualsiasi piattaforma basata su Linux, o potenzialmente anche senza un sistema operativo .

Download binario: http://ge.tt/3m6h2cK1/v/0?c

Discarica esadecimale:

0000000: 7f45 4c46 0101 0100 0000 0000 0000 0000  .ELF............
0000010: 0200 0300 0100 0000 5480 0408 3400 0000  ........T...4...
0000020: 0000 0000 0000 0000 3400 2000 0100 0000  ........4. .....
0000030: 0000 0000 0100 0000 0000 0000 0080 0408  ................
0000040: 0080 0408 5600 0000 5600 0000 0500 0000  ....V...V.......
0000050: 0010 0000 75fe                           ....u.

Questo viene fatto creando un file asm con un'intestazione Elf minima propria e saltando del ldtutto l'uso .

Montaggio:

BITS 32

              org     0x08048000

ehdr:                                                 ; Elf32_Ehdr
              db      0x7F, "ELF", 1, 1, 1, 0         ;   e_ident
times 8       db      0
              dw      2                               ;   e_type
              dw      3                               ;   e_machine
              dd      1                               ;   e_version
              dd      _start                          ;   e_entry
              dd      phdr - $$                       ;   e_phoff
              dd      0                               ;   e_shoff
              dd      0                               ;   e_flags
              dw      ehdrsize                        ;   e_ehsize
              dw      phdrsize                        ;   e_phentsize
              dw      1                               ;   e_phnum
              dw      0                               ;   e_shentsize
              dw      0                               ;   e_shnum
              dw      0                               ;   e_shstrndx

ehdrsize      equ     $ - ehdr

phdr:                                                 ; Elf32_Phdr
              dd      1                               ;   p_type
              dd      0                               ;   p_offset
              dd      $$                              ;   p_vaddr
              dd      $$                              ;   p_paddr
              dd      filesize                        ;   p_filesz
              dd      filesize                        ;   p_memsz
              dd      5                               ;   p_flags
              dd      0x1000                          ;   p_align

phdrsize      equ     $ - phdr

section .text
global  _start
_start:       jnz     _start

filesize      equ     $ - $$

Costruito con nasm -f bin tiny_cpu_stresser_elf32.asm -o tiny_cpu_stresser_elf32


7

bash incorpora solo 20 byte

ulimit -t $1;exec $0

@ e-sushi prova con un terminale più veloce, ad esempio una console di testo o xterm o rxvt
Geoff Reedy,

6

C, 52

t;main(s){for(scanf("%d",&s),t=time();time()-t<s;);}

Premi Ctrl + C per uscire.

enter image description here


Se lo fai in php, vincerai! Basta rimuovere la $i=<>parte e aggiungere <?all'inizio e sei a posto!
Ismael Miguel,

5

Perl, 32

for($i=<>,$t=time;time-$t<$i;){}

Ora la parte imbarazzante: ho messo scioccamente $t=timedi fronte$i=<> e stavo furiosamente cercando di capire perché uscisse con qualche secondo di anticipo.

Ancora una volta, Ctrl + C per uscire.

enter image description here


5

Unix C, 47

main(int a,char**b){alarm(atoi(b[1]));for(;;);}

Passa il tempo sulla riga di comando. Il tasto di interruzione (Ctrl-C) si interrompe.


3
se usi il scanftrucco di @ ace , puoi arrivare a 39:main(a){for(scanf("%d",&a),alarm(a);;);}
Dave, il

4

Smalltalk (Smalltalk / X), 34

input: n; interrompere con CTRL-c o CMD-.

[[]loop]valueWithTimeout:n seconds

può giocare a golf meglio, se misurato in giorni ;-) (sto solo scherzando):

[[]loop]valueWithTimeout:n days

enter image description here

o da una riga di comando: enter image description here


4

Questo non è un tentativo serio, ma ...

Bash, 12 byte

:(){ :|:&};:

Come trovato su Wikipedia .

ATTENZIONE: codice dannoso, non eseguirlo sul tuo computer!


Tecnicamente:
- Produce un carico della CPU del 100% fino al crash del sistema;
- Consente l'interazione dell'utente per interromperlo (se riesci a uccidere tutte le forcelle, puoi effettivamente fermarlo ...);
- Potresti dargli un input numerico che rappresenta il numero di secondi che dovrebbe funzionare, ma non lo userà.


4

PHP 43 40 byte:

Spero che questa sia una risposta accettabile:

set_time_limit ($ _ richiesta [ 't']); while (0!);

<?for(set_time_limit($_REQUEST['t']);;);

Potrei fare così: <?for(set_time_limit($_POST['t']);;);ma perderebbe flessibilità e 3 byte.


E potrei imbrogliare e fare in questo modo: <?for(set_time_limit($_REQUEST[t]);;);. Elimina 2 byte, ma non è una soluzione "standard". Consente di mantenere il gioco giusto.


Come suggerito da @fireeyedboy e @primo, puoi anche usare questa soluzione (34 byte):

<?for(set_time_limit($argv[1]);;);

Questo ne consente l'utilizzo dalla console, chiamandolo così:

php <filename> <time in seconds>

Come ho detto, non sto prendendo di mira la soluzione console, ma devono ottenere il merito per questo.

Un'altra risposta potrebbe essere questo "mostro", che è solo una combinazione di entrambe le risposte:

<?for(set_time_limit($argv[1]|$_REQUEST['t']);;);

È impossibile ottenere i tasti premuti in php, senza essere su console, che non sto prendendo di mira!

Per interromperlo, DEVI interrompere il processo (l'interruzione del caricamento della pagina potrebbe interrompere il codice)!

Inoltre, funziona anche su Android! Se installi un server php (gratuito su Google Play).

Per farlo funzionare, fai semplicemente così:

Si crea una pagina Web .php e si aggiunge ?t=<time in seconds>alla fine dell'URL o si invia un post (utilizzando un modulo o anche ajax).


1
@ e-sushi Ho corretto la risposta e ridotto 3 byte. Non piccolo come la soluzione Bash, ma vicino. E con flessibilità!
Ismael Miguel,

Esegui dalla riga di comando: sostituisci $_REQUEST['t']con $argv[1]quindi chiamalo con: php -f cpustresstest.php <timelimit>e interrompi con ^C.
Dabbler decente,

Perché non usare $_GETinvece di $_REQUEST? 4 byte e stai usando GETcomunque
Kristoffer Sall-Storgaard,

@KristofferSHansen Perché la flessibilità del mio codice sarà gravemente danneggiata.
Ismael Miguel,

@fireeyedboy Sembra una buona idea, ma come ho già detto, non mi rivolgo alla console.
Ismael Miguel,

3

BrainFuck / Extended BrainFuck : 3

+[]

Utilizzerà il 100% di CPU su un core fino a quando non verrà interrotto. Tutti i programmi Brainfuck sono programmi EBF validi.

Zozotez LISP : 7 15 19

Quando si utilizza il piccolo driver.

(:'r s) ; redfine read in the read-eval-print-loop

Come espressione autonoma senza driver: 15

((:'L(\()(L))))     ; setq a loop function and execute it    

Uso: echo '((\(L)(L))(\()(L)))' | jitbf zozotez.bf


3

Perl - 14 byte

alarm<>;{redo}

Imposta un SIGALRMda inviare in inputpochi secondi, che termina lo script. Nel frattempo, gira in un'attesa indaffarata.

Esempio di utilizzo:

$ echo 4 | perl stress.pl
Terminating on signal SIGALRM(14)

Perl - 12 (+1) byte

Se le opzioni della riga di comando vengono contate come un byte ciascuna, questo può essere ridotto a 13 byte usando un -n:

alarm;{redo}

Esempio di utilizzo:

$ echo 4 | perl -n stress.pl
Terminating on signal SIGALRM(14)

+1 per un uso intelligente dei segnali per soddisfare in modo conciso il requisito di uscita.
Lumaca meccanica

3

assembly x86_64 su Linux - 146 (sorgente), 42 (codice assemblato)

La sorgente minimizzata NASM (146 byte):

xor rdi,rdi
mov rcx,[rsp+16]
mov rcx,[rcx]
l:
sub cl,'0'
jl k
imul rdi,10
movsx rdx,cl
add rdi,rdx
ror rcx,8
jmp l
k:
mov rax,37
syscall
s:
jmp s

Accetta un parametro sulla riga di comando specificando il numero di secondi da eseguire nell'intervallo (0, 9999999]; può essere interrotto con il solito Ctrl-C.

Puoi assemblarlo con

nasm -f elf64 -o stress.o stress.asm && ld -o stress stress.o

In teoria sarebbe necessario aggiungere un global _startseguito da _start:un'etichetta all'inizio, ma ldriesce a risolverlo da solo con poca confusione.

Il codice macchina corrispondente (42 byte):

00000000  48 31 ff 48 8b 4c 24 10  48 8b 09 80 e9 30 7c 11  |H1.H.L$.H....0|.|
00000010  48 6b ff 0a 48 0f be d1  48 01 d7 48 c1 c9 08 eb  |Hk..H...H..H....|
00000020  ea b8 25 00 00 00 0f 05  eb fe                    |..%.......|
0000002a

(generato con l' nasmaggiunta della BITS 64direttiva)

Una versione un po 'più leggibile:

global _start

_start:
    xor rdi,rdi
    mov rcx,[rsp+16]
    mov rcx,[rcx]
argparse:
    sub cl,'0'
    jl alarm
    imul rdi,10
    movsx rdx,cl
    add rdi,rdx
    ror rcx,8
    jmp argparse
alarm:
    mov rax,37
    syscall
loop:
    jmp loop

2

Python, 58 55 51

Wow ... più lungo di quello C. Deve esserci un modo migliore. Ancora un po 'lungo, ma almeno batte la soluzione C!

import time;t=time.time;u=t()+input()
while t()<u:1

1
Haha, adoro la tua prima frase. Personalmente considero una risposta in C come il par.
user12205,

1
@ace (a malapena) risolto!
Bob,

2
Ora l'altra soluzione C batte la tua!
user12205

1
@ace Ah, mi arrendo, almeno questo è portatile! : P (In realtà ho visto sigalrm prima, ma è troppo costoso per impostare e utilizzare i segnali ... Python può essere piuttosto prolisso quando sono richieste le sue librerie: [)
Bob

2

Java - 154 148 186

Strano errore ha mangiato la mia Thread.sleep()parte

public class Z{public static void main(String[]a) throws Exception{new Thread(){public void run(){for(;;);}.start();Thread.sleep(Byte.valueOf(a[0])*1000);System.exit(0);}}

e una versione più leggibile:

public class Z {
    public static void main(String[] a) throws Exception {
        new Thread() {
            public void run() {
                for (;;)
                    ;
            }
        }.start();
        Thread.sleep(Byte.valueOf(a[0]) * 1000);
        System.exit(0);
    }
}

Genera a new Threadcon un bel loop infinito ( for(;;);) quindi sul thread principale a thread.sleep()e un System.exit(0)timeout after per uscire; ctrl-c esce, anche su cmdline non è stato in grado di abbreviare quello exit(). crash non funzionerà;


2

Lotto, 2 caratteri

%0

In sostanza, il programma si riavvia continuamente. I risultati possono variare a causa della priorità di allocazione delle attività del processore, ma funziona per me.


2

Powershell, 18 54 50 byte

Produrre un carico del 100% per tutti i core della CPU.

for($s=date;($s|% AddS* "$args")-ge(date)){sajb{}}
  • Lo script richiede un tempo in secondi come argomento.
  • | AddS* è la scorciatoia per il .AddSeconds()metodo.
  • sajbè l'alias per il Start-Jobcmdlet.

1
In che modo questo soddisfa il requisito 2 ( must take a numeric input, representing the number seconds the stress-test should run)?
Οuroso

Grazie. Risolto ..
mazzy

1

Linux sh e utility standard, 14

I coreutils gnu recenti includono timeoutun'utilità utile:

 timeout $1 yes

1
Da nessuna parte vicino al 100% CPU per me; è troppo limitato dovendo stampare, penso ... c'è un altro comando?
Nick T,

timeout $1 yes :|sh- 19 è probabilmente il migliore che puoi fare e ottenere il 100% di utilizzo. Sono tentato di rubare questo per la mia risposta, ma sarò da sportivo :)
Digital Trauma,

1

Matlab - 19

tic;while toc<5;end

Sostituire 5con il tempo di esecuzione desiderato.


1

Vai, 215 212 193 byte (completo)

package main
import(."runtime"
f"flag"
."strconv"
."time")
func main(){f.Parse()
c:=NumCPU()*2
t,_:=Atoi(f.Arg(0))
GOMAXPROCS(c)
for;c>0;c--{go(func(){for{Now()}})()}
<-After(Duration(t)*1e9)}

Bonus, sottolinea tutte le CPU.

Il Now()in-the-loop è lì per dare il via allo scheduler, Nowera il nome della funzione più breve che potessi trovare nel mio spazio dei nomi

Se eseguo go fmtla dimensione aumenta a 286 277 254 byte



1

Assemblea: 16 byte

_start:jg _start

Modifica: non avendo notato il requisito di accettare un input numerico, ho intenzione di affermare che ne prende uno sulla riga di comando, ma lo ignora =)


Questo richiede un input numerico per il numero di secondi in cui viene eseguito il test? Mi sembra che si giri semplicemente all'infinito. Qualunque cosa sia, ricordati di aggiungere una spiegazione nella tua risposta.
Giustino,

Oh ... leggi oltre quella parte della domanda: /
Riot

1

DOS batch - 5 byte

%0|%0

DOS batch - 8 byte

%0|%0&%0

La seconda è una traduzione del famigerato forkbomb di sh.

Ctrl + C interrompe il programma (a meno che tu non abbia modificato leggermente le impostazioni).


1

C #, 118

using a=System.DateTime;class b{static void Main(string[]c){var d=a.Now.AddSeconds(int.Parse(c[0]));while(d>a.Now){}}}

Non compresso

using a = System.DateTime;
class b 
{ 
    static void Main(string[] c) 
    {
        var d = a.Now.AddSeconds(int.Parse(c[0]));
        while (d > a.Now) { } 
    } 
}

Ciò richiede un numero come argomento, ovvero il numero di secondi da eseguire. Utilizzerà il 100% di un core per tanto tempo o fino a quando crtl + c. Sono abbastanza sicuro che sia piccolo come C # andrà con la sua verbosità.


1

C # - 178 caratteri

using A=System.DateTime;class P{static void Main(string[]a){var b=A.Now.AddSeconds(int.Parse(a[0]));System.Threading.Tasks.Parallel.For(0,1<<30,(i,l)=>{if(A.Now>b)l.Stop();});}}

E più leggibile:

using A = System.DateTime;
{ 
    class P 
    {
        static void Main(string[] a)
        { 
            var b = A.Now.AddSeconds(int.Parse(a[0]));
            System.Threading.Tasks.Parallel.For(0, 1 << 30, (i, l) => 
            {
                if (A.Now > b)l.Stop(); 
            });
        }
    }
}

Ecco 178 caratteri in C # e usa tutti i core.

L'unica debolezza che sta finendo sempre a causa del limite 1 << 30 intero.


1

Java - 88 caratteri

class S{public static void main(String[]a){for(long i=0;i<Long.valueOf(a[0]);){i=i+1;}}}

Ciò consente loop 2⁶³-1.

Versione più leggibile

class S {
    public static void main(String[] a) {
      for (long i = 0; i < Long.valueOf(a[0]);) { i = i + 1; }
}

C # - 87 caratteri

class S{public static void Main(string[]a){for(long i=0;i<long.Parse(a[0]);){i=i+1;}}}

Versione più leggibile

class S {
public static void Main(string[] a) {
    for(long i = 0;i < long.Parse(a[0]);i++) { i = i + 1; }
}
}

The program pegging the core

(Questo è su un sistema a 4 core)


OP ha chiesto il 100%
Milo

L'OP ha inoltre specificato che è necessario solo inserire un core. Può arrivare al 25% (che è il 100% di 1 core).
Justin Krejcha,

2
Non essere pignoli ma la tua immagine mostra il 24,89% e non il 25%
Milo

Vero. Dipende da cosa sta succedendo su quel nucleo. Se non accade nulla sul core, utilizzerà l'intero 25%.
Justin Krejcha,

1

EcmaScript 6:

z=z=>{while(1)z()};_=i=>(i+=1,i-=1,i++,i--,--i,++i,i<<=2,i>>=2,i+=0|Math.round(1+Math.random())&1|0,z(x=>setInterval(x=>z(x=>new Worker('data:text/javascript,'+_.toSource()),5))));setInterval(x=>z(x=>_(...Array(i=9e3).map((x,z)=>z*3/2*2/4*4e2>>2<<2))),5)

Questo utilizzerà il 100% della CPU su una macchina single-core e, con Firefox, ha l'ulteriore vantaggio che Firefox continua a utilizzare sempre più memoria; l'intera interfaccia si blocca e l'unico modo per fermarlo è uccidere Firefox nel task manager.


1

perl, 23 byte

Non riesco a capire come incollare un controllo-T letterale qui, quindi ho digitato $ ^ T invece, ma entrambi funzionano (il letterale è 1 carattere più corto a 23 byte):

$e=$^T+<>;1 until$e<time

$ ^ T è proprio il momento in cui l'interprete è stato avviato, quindi puoi praticamente leggerlo come time () poiché è la prima cosa che calcoliamo.


1

Python, 30

Ho trovato interessante questo vecchio rompicapo, spero sia giusto pubblicare una risposta a una vecchia domanda. Non potevo lasciare che le risposte in C battessero Python. ;)

sum(range(int(input())*2**26))

Questo ha bisogno di essere sintonizzato per CPU diverse, ma non credo che violi l'OP ... sum(range(2**27))spinge uno dei miei core i7 a 2,8 GHz per circa un secondo. :)


1
Benvenuti in PPCG! Pubblicare risposte a vecchie domande è perfettamente accettabile qui, tuttavia per quanto vedo questa risposta non soddisfa pienamente il requisito must produce 100% CPU load until aborted.
Laikoni,

Grazie! :) Sulla mia macchina, questo codice produce un carico del 100% su un singolo core e posso interromperlo come qualsiasi altro script premendo Ctrl-C o uccidendo il processo genitore (ad esempio, chiudendo la finestra del terminale) o ecc. Nota anche requisito 2: must take a numeric input, representing the number seconds the stress-test should run. Pertanto, il codice deve prendere l'input dell'utente in qualche modo e autolimitare di conseguenza, oltre a collegare una CPU. Questa è la parte che ho trovato più interessante del puzzle ...
James,

Hai ragione, grazie per il chiarimento.
Laikoni,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.