Assembly 如何阅读ISA反汇编?还有GPU流水线和等待状态

Assembly 如何阅读ISA反汇编?还有GPU流水线和等待状态,assembly,gpu,instruction-set,pipelining,cpu-cycles,Assembly,Gpu,Instruction Set,Pipelining,Cpu Cycles,我试图理解OpenCL编译器为了优化它而产生的机器代码。因此,我使用工具m2s opencl kc(来自multi2sim)离线编译我的*.cl文件,并将中间文件(开关:-a)保留为*.isa文件。这个*.isa包含一个“反汇编”部分,这似乎是我正在寻找的 注意:我的装配知识有点“旧”。我为像奔腾386/486这样的老CPU制作了汇编。所以我在阅读向量指令时遇到了问题,虽然我有一些关于向量指令的理论知识 [... OTHER STUFF ... ] ; -------- Disassembly

我试图理解OpenCL编译器为了优化它而产生的机器代码。因此,我使用工具m2s opencl kc(来自multi2sim)离线编译我的*.cl文件,并将中间文件(开关:-a)保留为*.isa文件。这个*.isa包含一个“反汇编”部分,这似乎是我正在寻找的

注意:我的装配知识有点“旧”。我为像奔腾386/486这样的老CPU制作了汇编。所以我在阅读向量指令时遇到了问题,虽然我有一些关于向量指令的理论知识

[... OTHER STUFF ... ]
; --------  Disassembly --------------------
00 ALU_PUSH_BEFORE: ADDR(32) CNT(6) KCACHE0(CB2:0-15) KCACHE1(CB0:0-15)
      0  x: MOV         R2.x,  0.0f
         z: SETGT_INT   R0.z,  1,  KC0[0].y
         t: MULLO_INT   ____,  R1.x,  KC1[1].x
      1  w: ADD_INT     ____,  R0.x,  PS0
      2  y: ADD_INT     R2.y,  PV1.w,  KC1[6].x
      3  x: PREDE_INT   ____,  R0.z,  0.0f      UPDATE_EXEC_MASK UPDATE_PRED
01 JUMP  POP_CNT(1) ADDR(9)
02 ALU: ADDR(38) CNT(5) KCACHE0(CB1:0-15)
      4  x: MOV         R2.x,  0.0f
         y: MOV         R3.y,  0.0f
         w: LSHL        ____,  R2.y,  2
      5  z: ADD_INT     R2.z,  KC0[0].x,  PV4.w
03 LOOP_DX10 i0 FAIL_JUMP_ADDR(8)
    04 ALU: ADDR(43) CNT(11) KCACHE0(CB2:0-15)
          6  y: ADD_INT     R3.y,  R3.y,  1
             w: LSHL        ____,  R3.y,  2
          7  x: SETGT_INT   R3.x,  KC0[0].y,  PV6.y
             z: ADD_INT     ____,  R2.z,  PV6.w
             w: ADD_INT     ____,  PV6.w,  8
          8  x: ASHR        R0.x,  PV7.w,  4
             y: LSHR        R0.y,  PV7.z,  2
             z: BFE_UINT    R0.z,  PV7.w,  0x00000002,  0x00000002
[... some more ... ]
我想知道的是命令前面的数字和字符的含义。据我所知,编译器生成了一些“复杂”指令,如:

00 ALU_PUSH_BEFORE: ADDR(32) CNT(6) KCACHE0(CB2:0-15) KCACHE1(CB0:0-15)
      0  x: MOV         R2.x,  0.0f
         z: SETGT_INT   R0.z,  1,  KC0[0].y
         t: MULLO_INT   ____,  R1.x,  KC1[1].x
      1  w: ADD_INT     ____,  R0.x,  PS0
      2  y: ADD_INT     R2.y,  PV1.w,  KC1[6].x
      3  x: PREDE_INT   ____,  R0.z,  0.0f      UPDATE_EXEC_MASK UPDATE_PRED
(问题:这是所谓的“超长指令词”吗?)

此“复杂”指令由多个“简单”指令组成,如下所示:

00 ALU_PUSH_BEFORE: ADDR(32) CNT(6) KCACHE0(CB2:0-15) KCACHE1(CB0:0-15)
      0  x: MOV         R2.x,  0.0f
         z: SETGT_INT   R0.z,  1,  KC0[0].y
         t: MULLO_INT   ____,  R1.x,  KC1[1].x
      1  w: ADD_INT     ____,  R0.x,  PS0
      2  y: ADD_INT     R2.y,  PV1.w,  KC1[6].x
      3  x: PREDE_INT   ____,  R0.z,  0.0f      UPDATE_EXEC_MASK UPDATE_PRED
这些“简单”指令似乎是每个向量单元的指令。这四个矢量单位由x、y、z和w引用。但什么是“t”?这是另一个向量单位吗?我为“Cypress”GPU编译了它

现在关于数字。。。这些只是“行号”吗? 前导零:复杂指令序列号。。。? 无前导零:简单指令序列号

我假设所有具有相同串行的“简单”指令都可以在一个周期内“逻辑”执行,前提是我们假设内存访问没有等待状态。例如,(上述复杂指令的)以下指令在周期0中“执行”:

      0  x: MOV         R2.x,  0.0f
         z: SETGT_INT   R0.z,  1,  KC0[0].y
         t: MULLO_INT   ____,  R1.x,  KC1[1].x
我所说的“执行”是指我们有某种(例如4周期)的流水线。这意味着上述指令应该在第0周期开始执行,并且应该在第3周期之后完成

关于管道的问题 如果下一条指令(例如“1”)将读取寄存器R2.x,会发生什么情况?它会读取R2.x的旧值(在指令“0”之前)还是指令“1”会被延迟,直到指令“0”结束?或者这可能是一种“不关心”的情况(产生未定义的结果),编译器必须注意这一点,而这永远不会发生

关于内存访问的问题 我假设可以在数据获取周期中执行对寄存器的访问,而无需等待。内存访问将需要一些额外的周期,具体取决于访问的内存类型:

  • “_private”内存应该主要映射到寄存器
  • __本地内存(在同一组的工作项之间共享高达64KB):在当前GPU中,我需要多少额外的周期
  • __全局内存:这应该是256MB到x GB的外部DRAM。在这里我需要额外的循环次数是多少?据我所知,此内存不会缓存到GPU设备
  • __常量内存应该类似于_全局内存,但使用_本地内存进行缓存
“ISA”有什么好的教程吗

问候,, Stefan

每个“编号”部分都是一个VLIW,例如:

  4  x: MOV         R2.x,  0.0f
     y: MOV         R3.y,  0.0f
     w: LSHL        ____,  R2.y,  2
这是一条使用三个可用ALU的指令,即“x”、“y”和“w”。它还可以使用构成最大并行指令的“z”和“t”,如:

  4  x: MOV         R2.x,  0.0f
     y: MOV         R3.y,  0.0f
     z: MOV         R3.z,  0.0f
     w: LSHL        ____,  R2.y,  2
     t: LSHL        ____,  R2.z,  4
尽管如此,这是一条单独的VLIW指令,它“馈送”着色器核心的所有五个ALU“通道”,然后在一个步骤中并行执行这五个操作

但什么是“t”?这是另一个向量单位吗

是的,“t”是第五个标量单位,称为“超越”,可以用来执行计算,如
sin(x)
cos(x)
。除此之外,它还可以执行普通的标量操作,但它的局限性在于,并非在“x”到“w”中可能执行的所有标量操作也可以在“t”中执行。因此,理想情况下,每个核心可以在一个步骤中执行五个标量操作。值得注意的是,与CPU上的SSE指令不同,这五个单元独立工作:每个单元在每个步骤中都可以执行自己的操作,而在SSE单元中,只有一个操作可以并行应用于多个数据。这基本上构成了SSE和VLIW架构之间的差异

那些

指令显然是特殊的指令,实际上并不在ALU上执行操作,比如从(片外)内存中获取数据,或者控制流指令

要获得内存延迟的估计值,请查看中的附录D-设备参数

\uu常量
内存与
\uu本地
内存不同:它在芯片上有自己的内存空间,所有工作项的内存空间都是相同的,根据文档,它的访问速度大约是
\uu本地
内存的两倍,因为工作项之间不需要一致逻辑

互联网上的一些来源指出,(AMD)GPU没有缓存,LDS内存应该用于显式模拟缓存。但在某些文档中,有对L1和L2缓存的引用


不管是哪种方式,请注意,当一个线程暂停等待数据时,GPU通过极快地切换执行“上下文”,在“隐藏”内存延迟方面非常出色。如果有足够多的并行任务可供选择,GPU可能总会找到一个准备好执行的任务,可以将其替换为需要等待的任务。

您在这里询问的是哪种GPU体系结构?ISA文件适用于AMD“Cypress”GPU。上述代码/所选GPU只是一个示例。请不要试图解释太“柏树”-具体。。。我需要以更一般的方式来理解这些事情。如果事情变得太复杂,无法在一篇简单的帖子中解释,那么一个链接到一个好的解释(例如教程、howto paper)也可以。Cypress,是的,我想我认识到了VLIW结构。您可以在这里下载关于Evergreen ISA的手册:您所询问的整个指令集和体系结构已经完全过时两次。我想说的是