我想用 tikz 复制这张图片
我的主要问题是正确的,因为我想利用 tikz 的自动功能进行绘图。截至目前,这平均能量损失是我最好的尝试:
\documentclass[]{standalone}
\usepackage{tikz}
\usetikzlibrary{arrows,positioning}
\usetikzlibrary{calc}
\tikzset{%
controlcpu/.pic={
\node[fill=yellow,
label={[anchor=north,
name=cu]90:Control Unit},
minimum width=3cm,
minimum height=2.5cm,
draw] (CU) {};
},
controlgpu/.pic={
\node[fill=yellow,
minimum width=3mm,
minimum height=1mm,
draw] (CU) {};
},
cachecpu/.pic={
\node[fill=red,
label={[anchor=north,
name=cache]90:Cache},
minimum width=3cm,
minimum height=2.5cm,
draw] (CU) {};
},
cachegpu/.pic={
\node[fill=red,
minimum width=3mm,
minimum height=1mm,
draw] (CUGPU) {};
},
alucpu/.pic={
\node[fill=green,
label={[anchor=north,
name=alu]90:ALU},
minimum width=3cm,
minimum height=2.5cm,
draw] (ALUCPU) {};
},
alugpu/.pic={
\node[fill=green,
minimum width=0.3cm,
minimum height=0.2cm,
draw] (ALUGPU) {};
},
dram/.pic={
\node[fill=orange,
label={[anchor=north,
name=dr]90:DRAM},
minimum width=3cm,
minimum height=2.5cm,
draw] (DRAM) {};
}
}
\begin{document}
\begin{tikzpicture}
\matrix[] (GRID) [column sep=1mm, row sep=1mm]
{\pic{controlgpu}; & \pic{cachegpu}; & \pic{alugpu}; & \pic{alugpu}; & \pic{alugpu}; & \pic{alugpu}; \pic{alugpu}; & \pic{alugpu}; \pic{alugpu}; & \pic{alugpu}; \pic{alugpu}; & \pic{alugpu}; \pic{alugpu}; & \pic{alugpu}; \pic{alugpu}; & \pic{alugpu}; & \pic{alugpu}; & \pic{alugpu}; \\
\pic{controlgpu}; & \pic{cachegpu}; & \pic{alugpu}; & \pic{alugpu}; & \pic{alugpu}; & \pic{alugpu}; \pic{alugpu}; & \pic{alugpu}; \pic{alugpu}; & \pic{alugpu}; \pic{alugpu}; & \pic{alugpu}; \pic{alugpu}; & \pic{alugpu}; \pic{alugpu}; & \pic{alugpu}; & \pic{alugpu}; & \pic{alugpu}; \\};
\end{tikzpicture}
\end{document}
这很丑陋,输出也很糟糕,因为我不知道如何把一个放在controlgpu
另一个cachegpu
之上
此外,我无法利用foreach
:也许是因为它需要“位置”(节点)方法?
我有两个问题
- 使用什么最有效的方法来重现它tikz 的矩阵?
- 可以使用吗
foreach
?foreach
推荐用于此类绘图吗?
例如,这里在官方指南中我的意思是使用来foreach
生成类似矩阵形状的 tikzfigure。
答案1
对于右图(GPU):
细胞由双环驱动:
\documentclass[tikz,
margin=3mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{arrows,
calc,
chains, % <-- added
positioning,
shapes.multipart% <-- added
}
\begin{document}
\begin{tikzpicture}[
node distance = 0.5mm and 0.5mm,
start chain = going right,
every node/.style = {on chain, inner sep=0pt, outer sep=0pt},
YO/.style = {% Yellow Orange boxes
rectangle split, rectangle split parts=2, draw,
rectangle split part fill = {yellow,red},
rectangle split empty part height=2mm-\pgflinewidth,
minimum width=4mm,
node contents={\nodepart{one}\nodepart{two}}},
G/.style = {% Green boxes
draw, fill=green!80, minimum size=4mm,
node contents={}},
O/.style = {% Orange boxes
draw, fill=orange,
inner ysep=3mm, inner xsep=4mm, align=left,
node contents={DRAM}},
]
\node (n11) [YO];
\foreach \i in {2,3,...,16}
\node (n1\i) [G];
% other rows
\foreach \j [count=\jx from 1] in {2,3,...,8}
{
\node (n\j1) [YO,below=of n\jx1];
\foreach \i in {2,3,...,16}
\node (n2\i) [G];
}
% dram
\path let \p1=($(n11.west)-(n116.east)$),
\n1={veclen(\y1,\x1)} in
node[below right=0.5 mm and 0 mm of n81.south west,
text width=\n1-8mm,
O, label={[inner sep=1mm]below:GPU}];
\end{tikzpicture}
\end{document}
类似地,也可以为 CPU 绘制左图。
答案2
\documentclass[border=2mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{calc}
\newcommand\unit[4] {\draw[fill=#2] (#4) rectangle +(#1);
\node[font=\sffamily\bfseries] at ($(#4)+0.5*(#1)$) {#3};
}
\newcommand\gpualu {\unit{ 0.9,0.9 }{green!30}{}}
\newcommand\gpucontrol{\unit{ 0.9,0.4 }{yellow!30}{}}
\newcommand\gpucache {\unit{ 0.9,0.4 }{red!30}{}}
\newcommand\dram {\unit{16.9,1.9 }{red!30}{DRAM}}
\newcommand\cpualu {\unit{ 4.1,2.05}{green!30}{ALU}}
\newcommand\cpucontrol{\unit{ 8.4,4.2 }{yellow!30}{Control}}
\newcommand\cpucache {\unit{16.9,4.2 }{red!30}{Cache}}
\begin{document}
\begin{tabular}[b]{c}
\begin{tikzpicture}[scale=0.4]
\dram { 0 ,-2.5}
\cpucache { 0 , 0}
\cpucontrol{ 0 ,4.4}
\cpualu { 8.6,4.4}
\cpualu {12.8,4.4}
\cpualu { 8.6,6.55}
\cpualu {12.8,6.55}
\node[font=\sffamily\bfseries] at (8.45,-3.5) {CPU};
\end{tikzpicture}\\
Central Processing Unit (CPU)
\end{tabular}
\qquad
\begin{tabular}[b]{c}
\begin{tikzpicture}[scale=0.4]
\dram{0,-2.5}
\foreach \i in {0,...,7}
\gpucontrol{0,1.1*\i+0.5}
\gpucache{0,1.1*\i}
\foreach \j in {1,...,16}
\gpualu{\j,1.1*\i};
\node[font=\sffamily\bfseries] at (8.45,-3.5) {GPU};
\end{tikzpicture}\\
Graphical Processing Unit (GPU)
\end{tabular}
\end{document}
编辑:关于我如何进行的一些解释。
相对或绝对定位:灵活的解决方案是将元素相对于彼此定位,从不指定任何坐标。缺点是您必须指定距离、组项等参数,这可能需要在文档中进行多次查找,并且可能变得不透明。对于这种独一无二的绘图,我选择了绝对定位方法,因为它保证更快、更紧凑。
主要结构是一个填充的矩形,偶尔带有标签。这就是它的
\node[size,color] at (position) {label}
作用。出于tikz
某些原因size
,和position
并不被同等对待:position
可以是无量纲的并且可以缩放,size
需要单位并且不缩放。由于此类绘图首先要绘制在某个方便的网格中,然后缩放到所需的大小,因此我必须将\draw
矩形缩放到:\draw[fill=#2] (#4) rectangle +(#1); % #2 fill color, #4 coordinates left bottom corner, #1 size = width,height
仅用于
\node
将标签定位在中心。\node at ($(#4)+0.5*(#1)$) {#3}; % #4 coordinates of left bottom corner, #1 vector to the top right corner, #3 label
该表达式
$(#4)+0.5*(#1)$
将矩形中心的坐标计算为“左下角加上到右上角距离的一半”。此坐标计算需要\usetikzlibrary{calc}
在序言中说明。我选择网格的左下角作为原点
(0,0)
,然后从那里开始上下移动。我选择 1×1 的正方形作为基本单位。为了分离 GPU-ALU,我选择给它们一个大小0.9,0.9
。后来我想在行之间留出更多空间,所以我在循环中为 y 坐标引入了因子 1.1\foreach
。