线程级并行(Thread Level Parallelism,TLP)是指在多个处理器或多个核心上同时执行多个线程,从而提高程序的性能和吞吐量。线程级并行的基本原理是利用程序中的数据或任务的并行性,将程序划分为若干个相对独立的子任务,分配给不同的线程执行,然后通过同步机制协调线程之间的数据依赖和通信。
线程具有状态和当前程序计数器,但线程通常共享单个进程的地址空间,允许线程轻松访问同一进程内其他线程的数据。 多线程是一种多线程共享处理器而不需要中间进程切换的技术。 线程之间快速切换的能力使得多线程能够用于隐藏管道和内存延迟。
多线程允许多个线程以重叠的方式共享单个处理器的功能单元。 相比之下,利用线程级并行性 (TLP) 的更通用方法是使用具有多个同时并行运行的独立线程的多处理器。 然而,多线程并不像多处理器那样复制整个处理器。 相反,多线程在一组线程之间共享大部分处理器核心,仅复制私有状态,例如寄存器和程序计数器。
线程级并行有两种主要的实现方式:
- 硬件多线程(Hardware Multithreading):这种方式是在处理器硬件层面上支持多个线程的并发执行,即一个处理器可以同时拥有多个程序计数器(PC)和寄存器堆,从而在一个时钟周期内执行多条指令。硬件多线程又分为两种类型:
- 超标量处理器(Superscalar Processor):这种方式是指在一个处理器内部集成多个功能部件(如算术逻辑单元、浮点单元、加载/存储单元等),从而在一个时钟周期内执行多条指令。超标量处理器需要使用复杂的指令调度和寄存器重命名技术来解决指令之间的数据依赖和资源冲突。超标量处理器可以实现指令级并行(Instruction Level Parallelism,ILP),也可以结合硬件多线程技术实现线程级并行。
下图 从概念上说明了以下处理器配置的处理器利用超标量资源的能力的差异:
下面是一个使用超标量处理器来实现线程级并行的例子:
假设我们有一个双发射(dual-issue)超标量处理器,它可以在每个时钟周期内发射两条指令,并且支持两个硬件线程。假设我们有以下两个线程:
```
Thread 0: Thread 1:
LD R1, 0(R2) LD R5, 0(R6)
ADD R3, R1, R4 SUB R7, R5, R8
ST R3, 0(R2) ST R7, 0(R6)
```
如果只有一个线程在运行,那么它需要6个时钟周期才能完成,如下所示:
```
Cycle Thread 0
1 LD R1, 0(R2)
2 stall (waiting for load result)
3 ADD R3, R1, R4
4 ST R3, 0(R2)
5 stall (waiting for store address)
6 stall (waiting for store data)
```
如果两个线程同时运行,并且交替发射指令,那么它们只需要4个时钟周期就能完成,如下所示:
```
Cycle Thread 0 Thread 1
1 LD R1, 0(R2) LD R5, 0(R6)
2 stall SUB R7, R5, R8
3 ADD R3, R1, R4 ST R7, 0(R6)
4 ST R3, 0(R2) stall
```
可以看出,线程级并行可以有效地利用处理器的资源,提高程序的性能和吞吐量。