在这个 TikZ 示例中,如何进行叠加并解决线条绘制问题?

在这个 TikZ 示例中,如何进行叠加并解决线条绘制问题?

我正在处理一张图片(代码如下),却遇到了两个问题:

  1. 从 DRAM 到 GPGPU 的线路连接不正确。此外,在重新生成图片时,DRAM 和 GPGPU 会分开。我该如何解决这个问题?
  2. 从 GPGPU 到集群的“缩放”线穿过集群。如何让集群“位于”缩放线之上?

下面是它当前的样子(由于问题 1 中描述的 DRAM 的不断移动,缩放线看起来很混乱):

在此处输入图片描述

如果有人能帮助我,我将不胜感激。

\documentclass[a4paper, 11pt]{article}

% Load packages
\usepackage{tikz}
\usepackage[sc,osf]{mathpazo}

% Load TikZ libraries
\usetikzlibrary{shapes,arrows}
\usetikzlibrary{fit}
\usetikzlibrary{backgrounds}
\usetikzlibrary{positioning}
\usetikzlibrary{calc}

% Define colors
\definecolor{lightGrey}{rgb}{0.9, 0.9, 0.9}
\definecolor{shade0}{named}{white}
\definecolor{shade1}{named}{lightGrey}
\definecolor{shade2}{rgb}{0.8, 0.8, 0.8}
\definecolor{shade3}{rgb}{0.65, 0.65, 0.65}
\definecolor{shade4}{rgb}{0.45, 0.45, 0.45}

% Text settings
\newcommand{\figureTextSize}{\tiny}

% Figure element lengths
\newlength{\gpgpuElemSize}
\setlength{\gpgpuElemSize}{8mm}
\newlength{\gpgpuElemSep}
\setlength{\gpgpuElemSep}{1mm}

% TikZ styles
\newcommand{\arrowStyle}{stealth}
\newcommand{\lineThickness}{semithick}
\tikzstyle{box} = [%
  draw,
  rectangle,
  \lineThickness,
]

\begin{document}

\begingroup
\figureTextSize
\newcommand{\drawSM}{%
  \begin{tikzpicture}[remember picture]
    % SPs
    \foreach \y in {1, ..., 4} {%
      \foreach \x in {1, ..., 2} {%
        \ifnum \x=1
          \ifnum \y=1
            \node [sp] (sp\y-\x) {SP};
          \else
            \pgfmathtruncatemacro\prevY{\y-1}
            \node [sp, below=of sp\prevY-\x] (sp\y-\x) {SP};
          \fi
        \else
          \pgfmathtruncatemacro\prevX{\x-1}
          \node [sp, right=of sp\y-\prevX] (sp\y-\x) {SP};
        \fi
      }
    }

    % SFUs
    \foreach \i in {1, ..., 2} {%
      \ifnum \i=1
        \path let \p1 = (sp1-1.south west),
                  \p2 = (sp1-2.north east)
               in
                 node [%
                   sfu,
                   minimum width=\x2-\x1-\pgflinewidth,
                   below right,
                 ] at ([%
                   yshift={-0.5\gpgpuElemSep},
                 ] sp4-1.south west) (sfu\i) {SFU};
      \else
          \pgfmathtruncatemacro\prevI{\i-1}
        \path let \p1 = (sp1-1.south west),
                  \p2 = (sp1-2.north east)
               in
                 node [%
                   sfu,
                   minimum width=\x2-\x1-\pgflinewidth,
                   below=of sfu\prevI,
                 ] (sfu\i) {SFU};
      \fi
    }

    % Fetch/Dispatch
    \node [issuer, right=of sp1-2] (issuer) {Fetch/Dispatch};

    % Register file
    \node [register, below=of issuer] (register) {Registers};

    % Instruction cache
    \node [cache, below=of register] (icache) {Inst. cache};

    % Constant cach
    \node [cache, below=of icache] (ccache) {Constant cache};

    % Shared memory
    \path let \p1 = (sfu2.south west),
              \p2 = (sfu1.north east),
              \p3 = (ccache.south west),
              \p4 = (ccache.north east)
           in
             node [%
               memory,
               minimum width=\x4-\x3-\pgflinewidth,
               minimum height=\y2-\y1-\pgflinewidth,
               below=of ccache,
             ] (sharedmem) {%
               \begin{tabular}{c}
                 Shared \\
                 memory
               \end{tabular}
             };
  \end{tikzpicture}
}
\begin{tikzpicture}[%
    auto,
    >=\arrowStyle,
    remember picture,
    every node/.style={%
      node distance=0.5\gpgpuElemSep,
    },
    splitted/.style={%
      rectangle split,
      rectangle split parts=2,
      rectangle split draw splits=false,
    },
    gpgpu/.style={%
      box,
      fill=shade2,
      splitted,
    },
    gpgpu-part/.style={%
      box,
      fill=shade3,
      minimum size=10mm,
    },
    dram/.style={%
      box,
      fill=shade1,
      minimum width=8mm,
      minimum height=5mm,
      node distance=\gpgpuElemSep,
    },
    connection/.style={%
      <->,
      \lineThickness,
    },
    cluster/.style={%
      box,
      fill=shade3,
      splitted,
    },
    sm/.style={%
      cluster,
      fill=shade0,
    },
    sp/.style={%
      box,
      fill=shade1,
      minimum size=0.5\gpgpuElemSize,
      inner sep=0pt,
    },
    sfu/.style={%
      sp,
    },
    register/.style={%
      box,
      fill=shade2,
      minimum height=0.5\gpgpuElemSize,
      minimum width=2\gpgpuElemSize,
      inner sep=0pt,
    },
    cache/.style={%
      register,
    },
    memory/.style={%
      register,
    },
    issuer/.style={%
      register,
      fill=shade3,
    },
    zoom-line/.style={%
      \lineThickness,
      dashed,
    },
  ]
  \node (all-parts) {%
    \begin{tikzpicture}[remember picture]
      % GPGPU - zoomed out
      \node [gpgpu] (gpgpu) {%
        GPGPU
        \nodepart{two}
        \begin{tikzpicture}[remember picture]
          % Clusters
          \foreach \y in {1, ..., 3} {%
            \foreach \x in {1, ..., 4} {%
              \ifnum \x=1
                \ifnum \y=1
                  \node [gpgpu-part] (gp\y-\x) {};
                \else
                  \pgfmathtruncatemacro\prevY{\y-1}
                  \node [gpgpu-part, below=of gp\prevY-\x] (gp\y-\x) {};
                \fi
              \else
                \pgfmathtruncatemacro\prevX{\x-1}
                \node [gpgpu-part, right=of gp\y-\prevX] (gp\y-\x) {};
              \fi
            }
          }
        \end{tikzpicture}
      };

      % DRAMs
      \node [below=of gpgpu, yshift=-2\gpgpuElemSep] {%
        \begin{tikzpicture}[remember picture]
          \foreach \i in {1, ..., 5} {%
            \ifnum \i=1
              \node [dram] (dram\i) {DRAM};
            \else
              \pgfmathtruncatemacro\prevI{\i-1}
              \node [dram, right=of dram\prevI] (dram\i) {DRAM};
            \fi

            % Connect DRAM with GPGPU
            \draw [connection] (dram\i) -- (dram\i |- gpgpu.south);
          }
        \end{tikzpicture}
      };
    \end{tikzpicture}
  };

  % Cluster - in detail
  \node [cluster, right=of all-parts, xshift=4\gpgpuElemSep] (cluster-big) {%
    Cluster
    \nodepart{two}
    \begin{tikzpicture}[remember picture]
      % SMs
      \node [sm] (sm1)               {SM \nodepart{two}\drawSM};
      \node [sm, right=of sm1] (sm2) {SM \nodepart{two}\drawSM};
      % Texture memory
      \path let \p1 = (sm1.south west),
                \p2 = (sm2.north east)
             in
               node [%
                 memory,
                 minimum width=\x2-\x1-\pgflinewidth,
                 below right,
               ] at ([%
                 yshift={-0.5\gpgpuElemSep},
               ] sm1.south west) (texturemem) {Texture memory};
    \end{tikzpicture}
  };

  % Zoom lines
  \draw [zoom-line] (gp2-4.north west) -- (cluster-big.north west);
  \draw [zoom-line] (gp2-4.north east) -- (cluster-big.north east);
  \draw [zoom-line] (gp2-4.south west) -- (cluster-big.south west);
  \draw [zoom-line] (gp2-4.south east) -- (cluster-big.south east);
\end{tikzpicture}
\endgroup

\end{document}

答案1

1)画出节点外的连接线。

2)可以使用层,将集群节点放在层中foreground,其余所有节点都放在main层中。

\documentclass[a4paper, 11pt]{article}

% Load packages
\usepackage{tikz}
\usepackage[sc,osf]{mathpazo}

% Load TikZ libraries
\usetikzlibrary{shapes,arrows}
\usetikzlibrary{fit}
\usetikzlibrary{backgrounds}
\usetikzlibrary{positioning}
\usetikzlibrary{calc}

% Define colors
\definecolor{lightGrey}{rgb}{0.9, 0.9, 0.9}
\definecolor{shade0}{named}{white}
\definecolor{shade1}{named}{lightGrey}
\definecolor{shade2}{rgb}{0.8, 0.8, 0.8}
\definecolor{shade3}{rgb}{0.65, 0.65, 0.65}
\definecolor{shade4}{rgb}{0.45, 0.45, 0.45}

% Text settings
\newcommand{\figureTextSize}{\tiny}

% Figure element lengths
\newlength{\gpgpuElemSize}
\setlength{\gpgpuElemSize}{8mm}
\newlength{\gpgpuElemSep}
\setlength{\gpgpuElemSep}{1mm}

% TikZ styles
\newcommand{\arrowStyle}{stealth}
\\
newcommand{\lineThickness}{semithick}
\tikzstyle{box} = [%
  draw,
  rectangle,
  \lineThickness,
]

\begin{document}
\pgfdeclarelayer{background}
\pgfdeclarelayer{foreground}
\pgfsetlayers{background,main,foreground}

\begingroup
\figureTextSize
\newcommand{\drawSM}{%
  \begin{tikzpicture}[remember picture]
    % SPs
    \foreach \y in {1, ..., 4} {%
      \foreach \x in {1, ..., 2} {%
        \ifnum \x=1
          \ifnum \y=1
            \node [sp] (sp\y-\x) {SP};
          \else
            \pgfmathtruncatemacro\prevY{\y-1}
            \node [sp, below=of sp\prevY-\x] (sp\y-\x) {SP};
          \fi
        \else
          \pgfmathtruncatemacro\prevX{\x-1}
          \node [sp, right=of sp\y-\prevX] (sp\y-\x) {SP};
        \fi
      }
    }

    % SFUs
    \foreach \i in {1, ..., 2} {%
      \ifnum \i=1
        \path let \p1 = (sp1-1.south west),
                  \p2 = (sp1-2.north east)
               in
                 node [%
                   sfu,
                   minimum width=\x2-\x1-\pgflinewidth,
                   below right,
                 ] at ([%
                   yshift={-0.5\gpgpuElemSep},
                 ] sp4-1.south west) (sfu\i) {SFU};
      \else
          \pgfmathtruncatemacro\prevI{\i-1}
        \path let \p1 = (sp1-1.south west),
                  \p2 = (sp1-2.north east)
               in
                 node [%
                   sfu,
                   minimum width=\x2-\x1-\pgflinewidth,
                   below=of sfu\prevI,
                 ] (sfu\i) {SFU};
      \fi
    }

    % Fetch/Dispatch
    \node [issuer, right=of sp1-2] (issuer) {Fetch/Dispatch};

    % Register file
    \node [register, below=of issuer] (register) {Registers};

    % Instruction cache
    \node [cache, below=of register] (icache) {Inst. cache};

        % Constant cach
    \node [cache, below=of icache] (ccache) {Constant cache};

    % Shared memory
    \path let \p1 = (sfu2.south west),
              \p2 = (sfu1.north east),
              \p3 = (ccache.south west),
              \p4 = (ccache.north east)
           in
             node [%
               memory,
               minimum width=\x4-\x3-\pgflinewidth,
               minimum height=\y2-\y1-\pgflinewidth,
               below=of ccache,
             ] (sharedmem) {%
               \begin{tabular}{c}
                 Shared \\
                 memory
               \end{tabular}
             };
  \end{tikzpicture}
}
\begin{tikzpicture}[%
    auto,
    >=\arrowStyle,
    remember picture,
    every node/.style={%
      node distance=0.5\gpgpuElemSep,
    },
    splitted/.style={%
      rectangle split,
      rectangle split parts=2,
      rectangle split draw splits=false,
    },
    gpgpu/.style={%
      box,
      fill=shade2,
      splitted,
    },
    gpgpu-part/.style={%
      box,
      fill=shade3,
      minimum size=10mm,
    },
    dram/.style={%
      box,
      fill=shade1,
      minimum width=8mm,
      minimum height=5mm,
      node distance=\gpgpuElemSep,
    },
    connection/.style={%
      <->,
      \lineThickness,
    },
    cluster/.style={%
      box,
      fill=shade3,
      splitted,
    },
    sm/.style={%
      cluster,
      fill=shade0,
    },
    sp/.style={%
      box,
      fill=shade1,
      minimum size=0.5\gpgpuElemSize,
      inner sep=0pt,
    },
    sfu/.style={%
      sp,
    },
    register/.style={%
      box,
      fill=shade2,
      minimum height=0.5\gpgpuElemSize,
      minimum width=2\gpgpuElemSize,
      inner sep=0pt,
    },
    cache/.style={%
      register,
    },
    memory/.style={%
      register,
    },
    issuer/.style={%
      register,
      fill=shade3,
    },
    zoom-line/.style={%
      \lineThickness,
      dashed,
    },
  ]
  \node (all-parts) {%
    \begin{tikzpicture}[remember picture]
      % GPGPU - zoomed out
      \node [gpgpu] (gpgpu) {%
        GPGPU
        \nodepart{two}
        \begin{tikzpicture}[remember picture]
          % Clusters
          \foreach \y in {1, ..., 3} {%
            \foreach \x in {1, ..., 4} {%
              \ifnum \x=1
                \ifnum \y=1
                  \node [gpgpu-part] (gp\y-\x) {};
                \else
                  \pgfmathtruncatemacro\prevY{\y-1}
                  \node [gpgpu-part, below=of gp\prevY-\x] (gp\y-\x) {};
                \fi
              \else
                \pgfmathtruncatemacro\prevX{\x-1}
                \node [gpgpu-part, right=of gp\y-\prevX] (gp\y-\x) {};
              \fi
            }
          }
        \end{tikzpicture}
      };

      % DRAMs
      \node [below=of gpgpu, yshift=-2\gpgpuElemSep] {%
        \begin{tikzpicture}[remember picture]
          \foreach \i in {1, ..., 5} {%
            \ifnum \i=1
              \node [dram] (dram\i) {DRAM};
            \else
              \pgfmathtruncatemacro\prevI{\i-1}
              \node [dram, right=of dram\prevI] (dram\i) {DRAM};
            \fi
          }

        \end{tikzpicture}
      };
    \end{tikzpicture}
  };

  % Connect DRAM with GPGPU
  \foreach \i in {1, ..., 5} %
    \draw [connection] (dram\i) -- (dram\i |- gpgpu.south);

  % Cluster - in detail
 \begin{pgfonlayer}{foreground}
  \node [cluster, right=of all-parts, xshift=4\gpgpuElemSep] (cluster-big) {%
    Cluster
    \nodepart{two}
    \begin{tikzpicture}[remember picture]
      % SMs
      \node [sm] (sm1)               {SM \nodepart{two}\drawSM};
      \node [sm, right=of sm1] (sm2) {SM \nodepart{two}\drawSM};
      % Texture memory
      \path let \p1 = (sm1.south west),
                \p2 = (sm2.north east)
             in
               node [%
                 memory,
                 minimum width=\x2-\x1-\pgflinewidth,
                 below right,
               ] at ([%
                 yshift={-0.5\gpgpuElemSep},
               ] sm1.south west) (texturemem) {Texture memory};
    \end{tikzpicture}
  };
  \end{pgfonlayer} 

  % Zoom lines
  \draw [zoom-line] (gp2-4.north west) -- (cluster-big.north west);
  \draw [zoom-line] (gp2-4.north east) -- (cluster-big.north east);
  \draw [zoom-line] (gp2-4.south west) -- (cluster-big.south west);
  \draw [zoom-line] (gp2-4.south east) -- (cluster-big.south east);

\end{tikzpicture}
\endgroup

\end{document}

在此处输入图片描述

答案2

请记住,TeX.tex每次解析文档的一行。因此,您在 中提供命令的顺序tikzpicture将提供一个层次结构,图形元素最终将在该层次结构中排版。为此,在回答您的第二个问题时(无需更正提供的代码),您需要将 移到Zoom lines之前Cluster(在GPGPU和之间Cluster)。这可能需要您重新编码部分(全部?)Cluster或使用不同的技术来获取cluster-big.<location>节点。

另一种不太优雅的方法是将整个内容排版Cluster两次。第二次是在打印之后Zoom lines

相关内容