Малюйте разом із процесором


289

Я натрапив на статтю, де студенти використовували мережевий трафік, щоб намалювати свій університет на графіку IPv6 в країні . [зображення]

Ваша мета проста у визначенні, але складна у здійсненні. Намалюйте текст MAIL (оскільки це одне з небагатьох слів, яке можна прочитати на 1D графіку) на графіку CPU.

Це має виглядати приблизно так:

Результат

Детальніше про те, що кваліфікується:

  • Код не повинен бути кросплатформенним (тому вам не знадобляться невідомі API для роботи).
  • Ви можете зафіксувати його в будь-якій загальній утиліті використання процесора.
  • Графік виглядає дещо гірше на іншій машині: я вам зараз довіряю.
  • Використання базового процесора% повинно бути безперервним, тому якщо ви генеруєте випадкову хвилю і виділите щось, що схоже на слово MAIL, це очевидно обман.
  • Ви можете вибрати максимальне завантаження, яке потрібно використовувати, але воно повинно бути досить значним, щоб чітко його бачити.
  • Ви повинні дотримуватися лінійності прикладу. (Для M це виглядає так: базовий%, потім раптовий приріст до вказаного максимуму, поступово падає на нижчий%, піднімається назад до максимуму і знову різке падіння до базового%.)
  • Якщо це не читається, виборці все-таки помітять.

Застосовуються стандартні лазівки. Опублікуйте зображення теж!


9
Я більше не бачу причини для закритого голосування. Я особисто вважаю це цікавим викликом, хоч і трохи специфічним для системи.
— seequ

6
Проблема, яку я бачу з кодом гольфу, полягає в тому, щоб оцінити, наскільки розбірливим є досить розбірливий. Якщо ви можете придумати спосіб визначити це об'єктивно, це значно покращить виклик, але це все-таки приємна ідея!
— Мартін Ендер

3
це насправді так само, як ваша картина, але я вам гарантую, якщо ви не викладете це словами, люди будуть тлумачити "намалювати ПОШУК" дуже вільно.
— Мартін Ендер

33
+1, це так абсурдно, що я майже посміхнувся на смерть ... "це безумство ..." "божевілля .. ЦЕ КОДЕГОЛЬФ !!!"
— vaxquis

5
Це жахливе запитання. Я б хотів, щоб я був досить розумним, щоб брати участь. Це насправді не має значення, мене цікавлять творчі рішення інших людей: P
— Chris Cirefice

Відповіді:


117

Пітона, 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

Кожному символу рядка відповідає одна секунда активності, від символу ASCII 0(максимум навантаження) до ~(дуже невелике навантаження). Програма працює на циклі, синхронізованому за часом, тому ви можете запускати кілька примірників для кращих результатів.

Я використовував Python 2.7.6 на OS X з Intel Core i7, але він повинен працювати на інших комп’ютерах, трохи налаштувавши (відрегулюйте 0.001). Скріншот нижче зроблений із значною фоновою активністю.

ПОЧТА

Оновлення - мені вдалося створити чіткіший графік із time()/10меншою частотою оновлення:

ПОЧТА

І нарешті, ось більш гольф-версія ( 123 байти ) та її результат :

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

250

Пітон, 358 281 268 221 194 байт

Монохромний такий у минулому році. Для використання двох процесів та системних дзвінків для досягнення двох кольорових графіків процесора!

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)

Вихід з монітора активності (OS X 10.9):

Графік монітора процесора Завантажте графік Графік діяльності монітора процесора

Повторюється на графіку історії CPU

Вихід з MenuMeters:

MenuMeters вихід

Всі виходи генерувались зі швидкістю оновлення 1с. Не виконується жодних значущих фонових завдань, хоча цей вихід досить легко вибиває будь-яке завдання з однопоточним процесором.

Цей код передбачає, що у вас є 8 ядер. Це має бути досить легко змінити для меншої кількості. Він портативний для систем Linux / UNIX (хоча він протестований лише на OS X) і повинен створювати однаковий двоколірний вихід для будь-якого монітора процесора, який може відрізняти користувача від системного процесорного часу.

По суті, це працює, виключаючи сім процесів, кожен з яких вирішить провести 1 секунду в режимі сну, спінінгу в користувальницькому режимі або обертання ядра. Спінінг в режимі ядра досягається за допомогою запиту великих даних у/dev/urandom , що примушує водія підтримувати /dev/urandomвитрачати багато "системних" процесорних циклів.

ЗРЕШЕНО [07/21]: Значно скорочено, використовуючи fork()замість multiprocessing.Process( /dev/urandomпрацює в будь-яких системах * NIX так чи інакше, тому це не зменшує мобільність). Однак зауважте, що програма тепер породжує фон завдання; вам, можливо, доведеться killall Python(або подібне) позбутися від процесорів, які їдять.


Я не втримався реалізувати ще кілька листів. Я отримав 16 літер плюс кілька символів:

~ /._ ПІН ANCHO ... ... VY

Повний алфавіт - "ACDFHILMNOPTUVWY", із символами "._ ~ / \". Напевно, може бути набагато більше символів, які можна представити.

Цілий код, що не використовується для додаткових літер:

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)

34
+1 для того, щоб надати літерам більше визначення, використовуючи 2 кольори
— DustinDavis

4
І +1 для створення
— листів,

1
Фактично A може бути належним чином виконаний (з отвором) з 4-х ниток. Потрібно встановити деякі кольори монітора процесора, щоб вони збігалися.
— Руслан

@Ruslan: Про який монітор процесора ти думаєш? Мій монітор показує лише один сукупний графік з 0 <= система <= користувач <= 100 у кожній точці (що робить "отвори" неможливими AFAIK).
— nneonneo

1
@nneonneo Я маю на увазі монітори, схожі на ваші. Дивіться цю картинку . Тут, якщо ми змінимо синій на зелений і червоний і фіолетовий на білий, ми отримаємо гарне "А" з отворами.
— Руслан

133

C (Intel Core Duo + OS X / Darwin), 248 байт

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

Цей код приблизно такий же портативний, як і Велика піраміда Хеопса. Вибач за те. Значення, що повертаються mach_absolute_time(), залежать від обладнання, але на моїй машині значення збільшується приблизно один раз на наносекунд.

Ось результат:

Слово "MAIL" відображається в моєму графіку історії процесора

Існує два графіки, оскільки процесор має два ядра. Я встановлюю максимальне завантаження процесора приблизно на 90%, оскільки процес може перемикатися між ядрами щоразу, коли я дзвоню usleep(). При 100% навантаженні процес прив’язаний до одного ядра, а результати нерозбірливі ( див. Це, наприклад )


1
Хороша робота! Це виглядає дуже цікаво. Не могли б ви опублікувати невелике пояснення коду? :)
— duci9y

1
я бачу брекети. чому в дужках для дужок є дужки? ви можете поставити сон у другий для останнього блоку циклу. я думаю, ти можеш трохи легше покататися на гольфі.
— bebe

Чи не могли ви розмістити декларацію та ініціалізацію uint64_tзмінних у заголовку наступного forциклу?
— Joey

74
+1: "Цей код приблизно такий же портативний, як і Велика Хеопсова піраміда"
— Уве Кеїм

@ Так ні, змінні C повинні бути оголошені на початку блоку. помістивши його в блок ініціалізації for for, викличе помилку. звичайно, це стосується лише <C99
— bebe

102

Рубі, 150 символів

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}

Це ще не все так коротко, але, на мій погляд, результат досить приємний, тому я зрозумів, що все-таки опублікую це. Як і у більшості інших рішень, вам, можливо, доведеться закріпити процес Ruby до певного ядра, префіксуючи його taskset -c $core.

Код - це просте поєднання спінінга / сну протягом певного часу, що повинно зробити його дещо портативним. Плавні градієнти створюються шляхом зміни співвідношення часу віджиму / сну.

MAIL письмовий монітор процесора

Зниження частоти вибірки процесора робить краї трохи кращими:

Нижня частота вибірки

Додавши в алфавіт AILMNUVWще кілька літер ( якісь впізнавані), ми також можемо написати кілька інших слів:

МАМА, МАЙ, СЕЛО

Ці фотографії генерувались із таким кодом:

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
}

Слова, які можна записати реалізованими літерами, можна знайти за допомогою

grep -E '^[aijlmnuvw]+$' /usr/share/dict/words 

4
+1 для розширення на більше слів!
— Chris Cirefice

Ви могли скласти слово "алюміній".
— Олівер Догерті-Лонг

@ OliverDaugherty-Long aluminium *
— TuxCrafting

1
@ TùxCräftîñg Алюміній - це варіант написання, який має зайву букву, і це найдовше слово, яке я думаю, що працює.
— Олівер Догерті-Лонг

48

Python, на Intel Pentium 4 3,0 ГГц, 180 166 145 141 138 байт

Подзвоніть з taskset -c 0 python cpu_graph_drawer.py.

taskset потрібен для обмеження процесу використання лише одного процесора / ядра (у моєму випадку гіперперебор).

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)

Результат не такий великий. Цей із набором завдань -c 1


9
Я хотів би побачити це на моніторі процесора, який не згладжує криві ...
— Szabolcs

1
Я теж, але мені не здається писати підкорений графік використання процесора, і gnome-system-monitorце єдине, що я знаю. Ви знайшли альтернативи, які мали б працювати на LMDE Cinnamon?
— користувач80551

Увімкніть "Намалюйте процесор як складену діаграму площі", а всі кольори встановіть на чорний.
— Техас Кале

@TejasKale Лінії все одно будуть вигнуті.
— user80551

FYI: a=[...]+[(.1,.2)]*10замість цього можна пограти в куполі .extend.
— nneonneo

46

Java 8, 482 символи

Кожен символ рядка означає кількість потоків, які будуть використані. Зображення зроблено на Intel Core i3 (2 ядра / 4 потоку).

результат

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

Редагувати : більше гольф-версії (322 символів), однакова функціональність:

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

1
Там є менше знаків, які інтерпретували як HTML і заплутували форматування.
— Девід Конрад

Наступні два рядки повинні пояснити наступні два рядки @ValekHalfHeart. Виконавець - це потік (асинхронний диспетчер завдань), що виконує завдання (тут циклі) до переривання. Після його створення основний потік чекає 1,5 секунди, а потім перериває всі завдання.
— PTwr

45
Щойно відкривши Eclipse, мій графік процесора написав "Простий протокол передачі пошти".
— лолеск

21

C, 78 байт

Ви ніколи не говорили, що ми не можемо прийняти вклад користувача, так що ..

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

Ця програма читає зі стандартного в, і кожен раз, коли вона читає персонаж, вона виконує безплатну процесору, витрачаючи цикл, а потім викликає основний знову. Ви контролюєте кількість використовуваного процесора часу, спамуючи клавішу введення з різною швидкістю.

Я провів це на Intel i3 4130T, який є досить новим процесором. Але ваш пробіг може відрізнятися, якщо він використовує більше або менше часу процесора, ніж це практично практично для вас, спробуйте зіграти зі зміною суми в циклі затримки.

Моя програма приголомшлива, тому що вона:

  • в основному є крос-платформою, вона повинна працювати з дуже невеликим вмістом на будь-якому * nix
  • перемагає питання
  • чудова гра з ендграми

Після кількох спроб я створив графік, який виглядав так:Графік процесора


Це допомагає обмежити його одним ядром процесора з набором завдань, a.la. taskset -c 1 [file]
— Вуг

2
Я не бачу нічого в проблемних вимогах, що говорить про те, що наші матеріали будуть викликані якyes | [program]
— Wug


1
"чудова гра з ендграйдом" змусила мене хахати. +1
— Крістоф

1
Але ця відповідь занадто гарна, лазівки прокляті xD!
— Чарівний восьминіг Урна
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.