Draw with your CPU

Python, 358 281 268 221 194 bytes

Monochrome is so last year. This uses multiple processes and syscalls to achieve two color CPU graphs!

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)

Output from Activity Monitor (OS X 10.9):

Activity Monitor CPU Load graph Activity Monitor CPU History graph

Repeats on the CPU History graph

Output from MenuMeters:

MenuMeters output

All outputs were generated with an update speed of 1s. No significant background tasks were running, though this output quite easily beats out any single-threaded CPU task.

This code assumes you have 8 cores. It should be pretty easy to modify for fewer/more. It is portable to Linux/UNIX systems (though it has only been tested on OS X), and should produce the same two-color output for any CPU monitor that can distinguish User from System CPU time.

Essentially, this works by forking off seven processes, each of which will choose to spend 1 second sleeping, spinning in usermode, or spinning the kernel. Spinning in kernel mode is achieved by requesting large globs of data from /dev/urandom, which forces the driver backing /dev/urandom to spend a lot of "system" CPU cycles.

EDITED [07/21]: Shortened significantly by using fork() instead of multiprocessing.Process (/dev/urandom only works on *NIX systems anyway so this doesn't reduce portability). Note however that the program now spawns background tasks; you may have to killall Python (or similar) to get rid of the CPU-eaters.


I couldn't resist implementing a few more letters. I got 16 letters, plus a few symbols:

~/._PIN ANCHO... ...VY

The complete alphabet is "ACDFHILMNOPTUVWY", with symbols "._~/\". There are probably lots more characters that can be represented.

Entirely ungolfed code for the extra letters:

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)

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

#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);}}}

This code is about as portable as the Great Pyramid of Cheops. Sorry about that. The values returned from mach_absolute_time() are hardware-dependent, but on my machine the value increments about once per nanosecond.

Here's the result:

The word "MAIL" shown in my CPU history graph

There are two graphs because the processor has two cores. I set the maximum CPU load to about 90% because the process is liable to switch between cores whenever I call usleep(). With a 100% load, the process is chained to one core and the results are illegible (see this, for example)


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

Each character of the string corresponds to one second of activity, from the ASCII character 0 (max load) through to ~ (very light load). The program runs on a time-synchronised loop, so you can run multiple instances for nicer results.

I used Python 2.7.6 on OS X with an Intel Core i7, but it should work on other computers with a bit of tweaking (adjust the 0.001). The screenshot below was taken with significant background activity.

MAIL

Update - I was able to produce a clearer graph with time()/10 and a lower update frequency:

MAIL

And finally, here's a more golfed version (123 bytes) and its result:

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

Tags:

Code Golf