Zeichne mit deiner CPU

289

Ich bin auf einen Artikel gestoßen, in dem Studenten Netzwerkverkehr verwendeten, um ihre Universität auf dem IPv6- Diagramm des Landes zu zeichnen . [Bild]

Ihr Ziel ist einfach zu sagen, aber schwer umzusetzen. Zeichnen Sie den Text MAIL (da dies eines der wenigen Wörter ist, die in einem 1D-Diagramm gelesen werden können) in das CPU-Diagramm.

Es sollte ungefähr so ​​aussehen:

Ergebnis

Ein bisschen mehr über die Qualifikationen herausarbeiten:

  • Der Code muss nicht plattformübergreifend sein (sodass Sie keine unbekannten APIs benötigen, um damit umzugehen).
  • Sie können es in jedem allgemeinen CPU-Nutzungsdienstprogramm erfassen, das Sie haben.
  • Die Grafik sieht auf einer anderen Maschine etwas schlechter aus: Diesmal vertraue ich Ihnen.
  • Die Basis-CPU-Auslastung% muss kontinuierlich sein. Wenn Sie also eine zufällige Welle erzeugen und etwas hervorheben, das wie das Wort MAIL aussieht, handelt es sich offensichtlich um Betrug.
  • Sie können die maximal zu verwendende Last auswählen, diese muss jedoch ausreichend groß sein, um sie klar erkennen zu können.
  • Sie müssen der Linearität des Beispiels folgen. (Für M sieht es so aus: Basis%, dann plötzlicher Anstieg auf das angegebene Maximum, allmählicher Abfall auf ein niedrigeres Prozent, Anstieg zurück auf das Maximum und plötzlicher Abfall auf das Basis-Prozent.)
  • Wenn es nicht lesbar ist, werden die Wähler es doch bemerken.

Es gelten Standardlücken. Poste die Bilder auch!

bebe
quelle
9
Ich sehe keinen Grund mehr für die enge Abstimmung. Ich persönlich finde das eine lustige Herausforderung, wenn auch ein wenig systemspezifisch.
Siehe auch
6
Das Problem, das ich beim Codegolf sehe, ist zu beurteilen, wie gut lesbar genug ist. Wenn Sie sich vorstellen können, dies objektiv zu spezifizieren, würde dies die Herausforderung erheblich verbessern, aber es ist trotzdem eine wirklich gute Idee!
Martin Ender
3
es ist wirklich genauso wie dein Bild, aber ich garantiere dir, wenn du es nicht in Worte fasst, werden die Leute "draw MAIL" sehr großzügig interpretieren.
Martin Ender
33
+1, es ist so absurd, dass ich mich fast totgelacht hätte ... "das ist Wahnsinn ..." "Wahnsinn ... DAS IST CODEGOLF !!!"
Vaxquis
5
Dies ist eine verdammt tolle Frage. Ich wünschte, ich wäre schlau genug, um daran teilzunehmen. Das ist eigentlich egal, ich interessiere mich für die kreativen Lösungen anderer Leute: P
Chris Cirefice

Antworten:

117

Python, 143

from time import*
while 1:
 sleep((ord('00012345654321000~~~D:6300036:D~~~000~~~000DDDD~~~~~'[int(time())%52])-48)*0.001);x=10**5
 while x:x-=1

Jedes Zeichen der Zeichenfolge entspricht einer Sekunde Aktivität, vom ASCII-Zeichen 0(maximale Belastung) bis zur ~(sehr geringen Belastung). Das Programm wird in einer zeitsynchronisierten Schleife ausgeführt, sodass Sie mehrere Instanzen ausführen können, um bessere Ergebnisse zu erzielen.

Ich habe Python 2.7.6 unter OS X mit einem Intel Core i7 verwendet, aber es sollte auf anderen Computern mit ein wenig Anpassung funktionieren 0.001. Der Screenshot unten wurde mit erheblichen Hintergrundaktivitäten aufgenommen.

MAIL

Update - Ich konnte ein übersichtlicheres Diagramm mit time()/10einer geringeren Update-Häufigkeit erstellen :

MAIL

Und zum Schluss noch eine Golf-Version ( 123 Bytes ) und das Ergebnis :

from time import*
while 1:
 sleep((ord('002464200~~A5005A~~00~~00DDD~~'[int(time()/2)%30])-48)*0.001);x=10**5
 while x:x-=1
grc
quelle
250

Python, 358 281 268 221 194 Bytes

Monochrom ist ja letztes Jahr. Dies verwendet mehrere Prozesse und Systemaufrufe, um zweifarbige CPU-Grafiken zu erhalten!

import os,time
A='%-99o'%int('t12q2lxqkap48euoej9429cstbnazl63ubyryteo49u',36)
for i in'0123456':
 t=os.fork()
 while t<1:T=int(time.time())%50;(time.sleep,(id,os.urandom)[i<A[T+49]])[i<A[T]](1)

Ausgabe von Activity Monitor (OS X 10.9):

Aktivitätsmonitor CPU-Lastdiagramm Aktivitätsmonitor-CPU-Verlaufsdiagramm

Wiederholt sich im CPU-Verlaufsdiagramm

Ausgabe von MenuMeters:

MenuMeters-Ausgabe

Alle Ausgaben wurden mit einer Aktualisierungsgeschwindigkeit von 1s generiert. Es wurden keine signifikanten Hintergrundaufgaben ausgeführt, obwohl diese Ausgabe jede Single-Threaded-CPU-Aufgabe ziemlich leicht übertrifft.

Dieser Code setzt voraus, dass Sie 8 Kerne haben. Es sollte ziemlich einfach sein, für weniger / mehr Änderungen vorzunehmen. Es ist portabel für Linux / UNIX-Systeme (obwohl es nur unter OS X getestet wurde) und sollte für jeden CPU-Monitor, der die CPU-Zeit des Benutzers von der des Systems unterscheiden kann, dieselbe zweifarbige Ausgabe erzeugen.

Dies funktioniert im Wesentlichen, indem sieben Prozesse abgebrochen werden, von denen jeder 1 Sekunde Schlaf, Drehen im Benutzermodus oder Drehen des Kernels verbringt. Das Starten im Kernel-Modus wird durch das Anfordern großer Datenmengen von erreicht /dev/urandom, was den Treiber-Backup /dev/urandomdazu zwingt , viele "System" -CPU-Zyklen zu verbringen.

EDITED [07/21]: Deutlich verkürzt durch Verwendung von fork()anstelle von multiprocessing.Process( /dev/urandomfunktioniert ohnehin nur auf * NIX-Systemen, sodass die Portabilität nicht beeinträchtigt wird). Beachten Sie jedoch, dass das Programm jetzt Hintergrundaufgaben erzeugt . Möglicherweise müssen Sie killall Python(oder ähnliches), um die CPU-Esser loszuwerden.


Ich konnte nicht widerstehen, noch ein paar Briefe umzusetzen. Ich habe 16 Buchstaben und ein paar Symbole:

~ /._ PIN ANCHO ... ... VY

Das vollständige Alphabet lautet "ACDFHILMNOPTUVWY" mit den Symbolen "._ ~ / \". Es gibt wahrscheinlich viel mehr Zeichen, die dargestellt werden können.

Völlig unbenutzter Code für die zusätzlichen Buchstaben:

from time import*
from multiprocessing import*

chars6 = {
'A': ('123456654321',
      '000123321000'),
'C': ('344556666666',
      '321110000000'),
'D': ('666666655443',
      '000000011123'),
'F': ('66666666666666',
      '00002222244444'),
'H': ('666664444466666',
      '000002222200000'),
'I': ('66666',
      '00000'),
'L': ('666662222222',
      '000000000000'),
'M': ('6665544334455666',
      '0004321001234000'),
'N': ('66665544336666',
      '00003322110000'),
'O': ('3445556666555443',
      '3221110000111223'),
'P': ('666666666555',
      '000003333444'),
'T': ('777776666677777',
      '444440000044444'),
'U': ('6666322236666',
      '4211000001124'),
'V': ('66654322345666',
      '33321000012333'),
'W': ('66542466424566',
      '43210133101234'),
'Y': ('66665433456666',
      '44333000033344'),
'_': ('1111111111',
      '0000000000'),
' ': ('000',
      '000'),
'.': ('12221',
      '10001'),
'~': ('44445544334444',
      '11223322112233'),
'/': ('2234566',
      '0012344'),
'\\': ('6654322',
       '4432100'),
}

s = 'ANCHOVY '
A = '000'.join(chars6[t][0] for t in s)
B = '000'.join(chars6[t][1] for t in s)

t=time()
f=open('/dev/urandom')
def F(n):
 while 1:T=int(time()-t)%len(A);[sleep,[].count,lambda x:f.read(4**9)][(n<int(A[T]))+(n<int(B[T]))](1)
for i in range(7):Process(target=F,args=(i,)).start()
F(7)
nneonneo
quelle
34
+1 für die Buchstaben mehr Definition mit 2 Farben geben
DustinDavis
4
Und +1 für die tabellenbasierte
Brieferstellung
1
Das A könnte tatsächlich richtig gerendert werden (mit einem Loch) mit 4 Gewinden. Müssten allerdings einige CPU-Monitorfarben so einstellen, dass sie übereinstimmen.
Ruslan
@ Ruslan: An welchen CPU-Monitor denkst du? Mein Monitor zeigt nur einen aggregierten Graphen mit 0 <= System <= Benutzer <= 100 an jedem Punkt (was "Löcher" unmöglich macht, AFAIK).
Nneonneo
1
@ Nneonneo Ich meine Monitore ähnlich wie bei Ihnen. Siehe dieses Bild . Wenn wir hier Blau in Grün und Rot und Lila in Weiß ändern, erhalten wir ein schönes "A" mit Löchern.
Ruslan
133

C (Intel Core Duo + OS X / Darwin), 248 Byte

#include <unistd.h>
#include <mach/mach_time.h>
#define M mach_absolute_time()
main(){char*s="JJJIHGFGHIJJJ@BDFHJJJHFDB@JJJJ@JJJJBBBBBBB";uint64_t i,t,y=1;for(;*s;s++){
for(i=40;i;i--){for(t=M+(*s&15)*9090909;t>M;)y*=7;usleep((11-(*s&15))*9091);}}}

Dieser Code ist ungefähr so ​​portabel wie die Cheops-Pyramide. Das tut mir leid. Die von zurückgegebenen Werte mach_absolute_time()sind hardwareabhängig, aber auf meinem Computer erhöht sich der Wert ungefähr einmal pro Nanosekunde.

Hier ist das Ergebnis:

Das Wort "MAIL" in meinem CPU-Verlaufsdiagramm

Es gibt zwei Diagramme, da der Prozessor zwei Kerne hat. Ich habe die maximale CPU-Auslastung auf ca. 90% festgelegt, da der Prozess bei jedem Aufruf zwischen den Kernen wechseln kann usleep(). Bei einer Auslastung von 100% ist der Prozess an einen Kern gebunden und die Ergebnisse sind unleserlich ( siehe dies zum Beispiel ).

zimperliches Ossifrage
quelle
1
Gut gemacht! Das sieht sehr interessant aus. Könnten Sie bitte eine kleine Erklärung des Codes posten? :)
duci9y
1
Ich sehe Zahnspangen. warum gibt es geschweifte Klammern in den for-Schleifen? Sie können usleep in den letzten Block der zweiten for-Schleife setzen. Ich denke, Sie können ein wenig leichter Golf spielen.
Be
Könnten Sie die Deklaration und Initialisierung der uint64_tVariablen nicht in den Header der folgenden forSchleife schreiben?
Joey
74
+1: "Dieser Code ist ungefähr so ​​portabel wie die Große Cheopspyramide"
Uwe Keim
@ Nein, C-Variablen müssen am Anfang eines Blocks deklariert werden. Wenn Sie es in den Initialisierungsblock von for setzen, wird ein Fehler ausgegeben. natürlich gilt sie nur für <C99
bebe
102

Ruby, 150 Zeichen

a=(0..15).map{|i|[0.9-3*i*=0.02,i]}
[9,*a[0,11],*(z=a.reverse)[5,11],11,*z,*a,2,11,6,*[0.2]*9].map{|x,y|c=Time.now
1until Time.now-c>x/3
sleep y||x%3}

Das ist noch nicht so kurz, aber meiner Meinung nach ist die Ausgabe ziemlich gut, also dachte ich mir, ich würde das trotzdem posten. Wie bei den meisten anderen Lösungen müssen Sie den Ruby-Prozess möglicherweise an einen bestimmten Kern binden, indem Sie ihm das Präfix voranstellen taskset -c $core.

Der Code ist eine einfache Kombination aus Drehen / Schlafen für eine bestimmte Zeit, die es etwas tragbar machen sollte . Durch Variation des Verhältnisses von Spin / Sleep-Zeit werden gleichmäßige Verläufe erzeugt.

MAIL geschriebener CPU-Monitor

Durch Verringern der CPU-Abtastfrequenz sehen die Kanten etwas besser aus:

Niedrigere Abtastfrequenz

Durch Hinzufügen einiger weiterer Buchstaben zum Alphabet ( AILMNUVWsind etwas erkennbar) können wir auch einige andere Wörter schreiben:

MAMA, MAW, VILLAIN

Diese Bilder wurden mit folgendem Code erzeugt:

def gradient num_samples, direction, base = 0.3, increment = 0.02, scale = 1
    range = [*0..num_samples]

    samples = case direction
        when :up then range.reverse
        when :down then range
        when :updown then range.reverse + range
        when :downup then range + range.reverse
    end

    samples.map{|i|
        i *= increment
        [base - scale * i, i]
    }
end

# letters are defined as a series of pairs of (spin-time, sleep-time)
# with the time in seconds
THIN_A = gradient(15, :updown, 0.2, 0.2/15)
A = gradient(15, :updown)
I = 2,0
L = 1.5,0, [[0.1,0.2]]*9
M = 2,0, gradient(9, :downup), 2,0
N = 1,0, gradient(9, :down), 2,0
U = 1,0, gradient(9, :downup, 0.1, 0.03, 0.1), 1,0
V = 0.5,0, gradient(12, :downup, 0.25, 0.02), 0.5,0
W = 0.5,0, [gradient(12, :downup, 0.25, 0.02)]*2, 0.5,0

[A,I,L,M,N,U,V,W].map{|i|
    # add 2 second pause after each letter
    i + [0,2]
}.flatten.each_slice(2){|x,y|
    # spin, then sleep
    c = Time.now
    1 until Time.now-c > x
    sleep y
}

Wörter, die mit den implementierten Buchstaben geschrieben werden können, finden Sie mit

grep -E '^[aijlmnuvw]+$' /usr/share/dict/words 
Ventero
quelle
4
+1 für die Erweiterung in mehr Wörter!
Chris Cirefice
Sie hätten das Wort "Aluminium" machen können.
Oliver Daugherty-Long
@ OliverDaugherty-Long Aluminium *
TuxCrafting
1
@ TùxCräftîñg Aluminium ist eine Variante, die einen zusätzlichen Buchstaben enthält und das längste Wort ist, das mir dazu einfällt.
Oliver Daugherty-Long
48

Python auf Intel Pentium 4 3.0 GHz, 180 166 145 141 138 Bytes

Mit anrufen taskset -c 0 python cpu_graph_drawer.py.

taskset wird benötigt, um den Prozess auf die Verwendung nur einer CPU / eines Kerns zu beschränken (Hyperthreading in meinem Fall).

from time import*;c=clock
a=[(3,.8),(3,5),(4,5),(1.3,5),(1.3,0)]
a.extend([(.1,.2)]*10)
for x,y in a:
    t=c()
    while c()-t<x:pass
    sleep(y)

Ergebnis ist nicht so toll. Diesmal mit dem Task-Set -c 1

user80551
quelle
9
Ich würde dies gerne mit einem CPU-Monitor sehen, der die Kurven nicht glättet ...
Szabolcs
1
Ich auch, aber ich habe keine Lust, eine Grafik zur CPU-Auslastung zu schreiben, und gnome-system-monitorweiß nur, was ich weiß. Haben Sie Alternativen, die mit LMDE Cinnamon laufen würden?
User80551
Aktivieren Sie die Option "CPU als gestapeltes Flächendiagramm zeichnen" und setzen Sie alle Farben auf Schwarz.
Tejas Kale
@ TejasKale Die Linien wären immer noch gekrümmt.
User80551
Zu Ihrer Information: Sie können eine Reihe von Zeichen spielen, indem Sie a=[...]+[(.1,.2)]*10anstelle von verwenden .extend.
Nneonneo
46

Java 8, 482 Zeichen

Jedes Zeichen in der Zeichenfolge steht für die Anzahl der Threads, die verwendet werden. Bild auf Intel Core i3 (2 Kerne / 4 Threads) aufgenommen.

Ergebnis

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Mail{
public static void main(String[] args) throws InterruptedException{
Thread.sleep(15000);
for(char c:"123432234321000012343210000444000044441111111".toCharArray()){
ExecutorService executorService = Executors.newScheduledThreadPool(4);
for(int i=1;i<c-48;i++)executorService.execute(()->{while(!Thread.interrupted());});
Thread.sleep(1500);
executorService.shutdownNow();
}}}

Bearbeiten : mehr Golf-Version (322 Zeichen), gleiche Funktionalität:

import java.util.concurrent.*;
class M{
public static void main(String[]a)throws Exception{
for(int c:"123432234321000012343210000444000044441111111".toCharArray()){
ExecutorService s=Executors.newFixedThreadPool(4);
while(c>48){c--;s.execute(()->{while(!Thread.interrupted());});}
Thread.sleep(1500);
s.shutdownNow();
}}}
Tomáš Dvořák
quelle
1
Dort gibt es ein Zeichen, das als HTML interpretiert und die Formatierung durcheinander gebracht wurde.
David Conrad
@ValekHalfHeart Die nächsten beiden Zeilen sollten es erklären. Executor ist ein Thread (asynchroner Task-Manager) , der Tasks (hier Schleifen) bis zur Unterbrechung ausführt. Nach dem Erstellen wartet der Haupt-Thread 1,5 Sekunden und unterbricht dann alle Aufgaben.
PTwr
45
Durch einfaches Öffnen von Eclipse schrieb mein CPU-Diagramm "Simple Mail Transfer Protocol".
Lolesque
21

C 78 Bytes

Du hast nie gesagt, dass wir keine Benutzereingaben akzeptieren könnten, soooo.

#include <unistd.h>
int main(){int x=0;for(;x<1<<26;++x);read(0,&x,1);main();}

Dieses Programm liest vom Standard ein und führt jedes Mal, wenn es ein Zeichen liest, eine unbegründete CPU-Verschwendung für die Schleife aus und ruft dann erneut main auf. Sie steuern die verwendete CPU-Zeit, indem Sie die Eingabetaste mit unterschiedlichen Geschwindigkeiten spammen.

Ich habe dies auf einem Intel i3 4130T ausgeführt, bei dem es sich um einen relativ neuen Prozessor handelt. Ihre Laufleistung kann jedoch variieren. Wenn Sie mehr oder weniger CPU-Zeit verbrauchen, als für Sie praktisch ist, versuchen Sie, mit dem Verschiebungsbetrag in der Verzögerungsschleife zu spielen.

Mein Programm ist fantastisch, weil es:

  • ist meist plattformübergreifend, es sollte auf keinem * nix mit sehr wenig Geigen funktionieren
  • besiegt die Frage
  • Tolles Endgame-Spiel

Nach ein paar Versuchen habe ich ein Diagramm erstellt, das so aussah:CPU-Grafik

Wug
quelle
Es hilft, es mit dem Task-Set a.la auf einen CPU-Kern zu beschränken. taskset -c 1 [file]
Wug
2
Ich sehe in den Problemanforderungen nichts, was besagt, dass unsere Einsendungen aufgerufen werden alsyes | [program]
Wug
12
Standard-Lücke ... fällt auch unter meta.codegolf.stackexchange.com/a/1085/6699 .
Nneonneo
1
"Great Endgame Play" hat mich hart gemacht. +1
Christoph
1
Diese Antwort ist allerdings zu gut, Lücken müssen verdammt sein xD!
Magic Octopus Urn