Check out my first novel, midnight's simulacra!
Dot
From dankwiki
SVG
- graphviz tools generate svg via -Tsvg
- notugly is some XSL to beautify dot's SVG output
Examples
Generated using Graphviz 2.20.2 and postprocessing via xsltproc and notugly. I hand-wrote the dot sources.
Packed Record
digraph G { subgraph clusterOpteron { label="Quad-Core Opteron" node [shape=record]; struct3 [label="{ {C0|C1|C2|C3}|{L1/L2|L1/L2|L1/L2|L1/L2}|SRI\ (SysReq Interface)|<xbar>XBAR (Crossbar Switch)|{MCH|ncHT-HB|HT0|HT1}}"]; } }
Rectilinear arrangement A
digraph G { subgraph clusterOpteronNUMA { label = "2x 'Deneb' Phenom II X4 910 (45nm, AM3). 8 threads." Deneb0->Deneb1 [dir="both" label="2GHz 16-bit bidir\n8GB/s HyperTransport 3.0" color="blue"] DDR0 -> Deneb0 [dir="both" color="lightblue"] DDR1 -> Deneb1 [dir="both" color="lightblue"] HostBus -> Deneb0 [dir="both" color="darkgreen"] HostBus -> Deneb1 [dir="both" color="darkgreen"] { rank=same; Deneb0 Deneb1 } { rank=same; DDR0 DDR1 } Deneb0 [style=filled fillcolor=steelblue shape=box] Deneb1 [style=filled fillcolor=steelblue shape=box] DDR0 [style=filled fillcolor=grey shape=invhouse] DDR1 [style=filled fillcolor=grey shape=invhouse] HostBus [style=filled fillcolor=green shape=Msquare] } }
Rectilinear arrangement B
digraph G { nodesep="1" subgraph clusterNehalemSMP { DDR0 -> Nehalem0 [dir="both" color="lightblue"] DDR0 -> Nehalem1 [dir="both" color="lightblue"] Nehalem0->Nehalem1 [dir="both" label="25.6GB/s QuickPath" color="blue"] subgraph clusterNehalemSMP0 { label="DRAM may or may not be shared."; style=filled; color=lightgrey; { rank=same; DDR0 } { rank=same; Nehalem0 Nehalem1 } } Nehalem2->Nehalem3 [dir="both" label="25.6GB/s QuickPath" color="blue"] Nehalem2 -> DDR1 [dir="both" color="lightblue"] Nehalem3 -> DDR1 [dir="both" color="lightblue"] subgraph clusterNehalemSMP1 { labelloc="b"; label="Each package gets its own MCH and L3 cache,\neach core its own (split) L1 and (unified) L2."; style=filled; color=lightgrey; { rank=same; Nehalem2 Nehalem3 } { rank=same; DDR1 } } label = "4x 'Nehalem-EP' E5520 HT Core i7 (45nm LGA1336). 32 threads." Nehalem1->Nehalem2 [dir="both" color="blue"] Nehalem3->Nehalem0 [dir="both" color="blue"] Nehalem0->HostBus [dir="both" color="darkgreen"] Nehalem1->HostBus [dir="both" color="darkgreen"] HostBus->Nehalem2 [dir="both" color="darkgreen"] HostBus->Nehalem3 [dir="both" color="darkgreen"] Nehalem0 [style=filled fillcolor=steelblue shape=box label="4x 2-way cores"] Nehalem1 [style=filled fillcolor=steelblue shape=box label="4x 2-way cores"] Nehalem2 [style=filled fillcolor=steelblue shape=box label="4x 2-way cores"] Nehalem3 [style=filled fillcolor=steelblue shape=box label="4x 2-way cores"] DDR0 [style=filled fillcolor=grey shape=invtrapezium] DDR1 [style=filled fillcolor=grey shape=trapezium] HostBus [style=filled fillcolor=green shape=Msquare] } }
Large flow
digraph G { nodesep="0.5" subgraph clusterPrime { labelloc="b"; compound="true" subgraph clusterKernel { label="Kernelspace (Linux epoll, FreeBSD kqueue, etc...)" style=filled; color=cadetblue; wqueue0 [style=filled fillcolor=steelblue shape=Mdiamond] wqueueN [style=filled fillcolor=steelblue shape=Mdiamond] wqueue0 -> nics [dir=both] nics [style="filled,diagonals" fillcolor=greenyellow label="Devices/IPC"] nics -> wqueueN [dir=both] { rank=same; wqueue0 wqueueN nics } } subgraph clusterUser { label="Userspace (libtorque-enabled process)"; style=filled; color=gold; evqueueN [style="diagonals,filled" fillcolor=mediumpurple shape=invtrapezium group="evq"] evqueue0 [style="diagonals,filled" fillcolor=mediumpurple shape=invtrapezium group="evq"] wqueue0 -> evqueue0 [dir=both style=bold color="blue:purple"] wqueueN -> evqueueN [dir=both style=bold color="blue:purple"] evqueue0 -> evqueueN [label="About sqrt(cpus) evqueues, usually" dir=both style=dotted color=maroon] API -> evqueue0 [style=bold color=purple] API -> evqueueN [style=bold color=purple] API [style=filled fillcolor=green shape=box group="evq"]; { rank=same; evqueue0 evqueueN } node [shape=record]; thr0 [label="<t0>T0|<t1>T1|<t2>T2|<tN>TN"]; thrN [label="<t0>T0|<t1>T1|<t2>T2|<tN>TN"]; color=red; evqueue0 -> thr0:t0 [color=blue] evqueue0 -> thr0:t1 [color=blue] evqueue0 -> thr0:t2 [color=blue] evqueue0 -> thr0:tN [color=blue] evqueueN -> thrN:t0 [color=blue] evqueueN -> thrN:t1 [color=blue] evqueueN -> thrN:t2 [color=blue] evqueueN -> thrN:tN [color=blue] { rank=same; thr0 thrN } thr0 -> sigtable [color=lightblue style=bold] thr0 -> fdtable [color=lightblue style=bold] thr0 -> twheel [color=lightblue style=bold] thrN -> sigtable [color=lightblue style=bold] thrN -> fdtable [color=lightblue style=bold] thrN -> twheel [color=lightblue style=bold] fdtable [style=filled fillcolor=lightgreen shape=box label="fd monads\n(array)"] twheel [style=filled fillcolor=lightgreen shape=box label="timer monads\n(hwheel or array)"] sigtable [style=filled fillcolor=lightgreen shape=box label="sig monads\n(array)"] sigtable -> fdtable [color=lightblue label="AIO"] fdtable -> buf [color=lightblue] fdtable -> dnsssl [color=lightblue] twheel -> dnsssl [color=lightblue] buf -> API { rank=same; sigtable fdtable twheel } dnsssl -> API dnsssl [style=filled fillcolor=lightgreen shape=box label="DNS, SSL/TLS\n(adns, OpenSSL)"] buf [style=filled fillcolor=lightgreen shape=box label="Buffering\n(arch-adaptive)"] node [shape=record]; appthr [label="<tmain>Main\nthread|<t1>T1|<t2>T2|<tN>TN"]; cbs [style=filled fillcolor=orange shape=box label="Registered callbacks"]; cbs -> appthr [dir=both color=darkgreen] sigtable -> cbs [color=green] fdtable -> cbs [color=green] twheel -> cbs [color=green] buf -> cbs [color=green] dnsssl -> cbs [color=green] cbs -> API; appthr -> API; /*API -> fdtable [color=blueviolet] API -> sigtable [color=blueviolet] API -> twheel [color=blueviolet]*/ } } }
PNG
Generated with dot -Tpng, no postprocessing.
Multiple records
digraph G { nodesep="0.1" rankdir=RL; subgraph clusterPrime { label="SHA-1 input layout\ (b\ hashes\ per\ thread)\nNx1x1 block geometry,\ Gx1x1\ grid\ geometry"; labelloc="b"; compound="true" subgraph clusterKernel { color=darkgoldenrod; style=filled; label="bl0"; b0 [style=filled,width=5,shape=record,label="{ {Hash\ set\ 1\n(512n\ bits)}\ |{T0[0x0]|T0[0x1]|T0[...]|T0[0xf]}|{T1[0x0]|T1[0x1]|T1[...]|T1[0xf]}|{...|...|...|...}|{Tn[0x0]|Tn[0x1]|Tn[...]|Tn[0xf]}}"]; b1 [style=filled,width=5,shape=record,label="{ {Hash\ set\ b\n(512n\ bits)}\ |{T0[0x0]|T0[0x1]|T0[...]|T0[0xf]}|{T1[0x0]|T1[0x1]|T1[...]|T1[0xf]}|{...|...|...|...}|{Tn[0x0]|Tn[0x1]|Tn[...]|Tn[0xf]}}"]; label="Input to block 1 (512*n*b bits)"; } subgraph clusterUser { color=darkkhaki; style=filled; label="bl0"; b2 [style=filled,width=5,shape=record,label="{ {Hash\ set\ 1\n(512n\ bits)}\ |{T0[0x0]|T0[0x1]|T0[...]|T0[0xf]}|{T1[0x0]|T1[0x1]|T1[...]|T1[0xf]}|{...|...|...|...}|{Tn[0x0]|Tn[0x1]|Tn[...]|Tn[0xf]}}"]; b3 [style=filled,width=5,shape=record,label="{ {Hash\ set\ b\n(512n\ bits)}\ |{T0[0x0]|T0[0x1]|T0[...]|T0[0xf]}|{T1[0x0]|T1[0x1]|T1[...]|T1[0xf]}|{...|...|...|...}|{Tn[0x0]|Tn[0x1]|Tn[...]|Tn[0xf]}}"]; label="Input to block G (512*n*b bits)"; } } }