Data-Level Parallelism in Vector, SIMD, and GPU Architectures
4.1 Introduction
P282
three advantage of SIMD compared to MIMD
- is not only the matrix-oriented computations of scientific computing but also the media-oriented image and sound processing and machine learning algorithms
- MIMD architecture needs to fetch one instruction per data operation, single instruction multiple data (SIMD) is potentially more energy-efficient since a single instruction can launch many data operations
- biggest advantage of SIMD versus MIMD is that the programmer continues to think sequentially yet achieves parallel speedup by having parallel data operations.
So where is the description of MIMD in this textbook
| Property | vector architectures | multimedia SIMD instruction set extensions | graphics processing units (GPUs) |
|---|---|---|---|
| Advantage | easier to understand and to compile to than other SIMD variations | ||
| Disadvantage | but they were considered too expensive for microprocessors until recently |
This environment has a system processor and system memory in addition to the GPU and its graphics memory. In fact, to recognize those distinctions, the GPU community refers to this type of architecture as heterogeneous.
P283
vector architectures are supersets of themultimedia SIMD instructions, including a better model for compilation
4.2 Vector Architecture
In practice, developers can express many of the programs that ran well on complex out-oforder designs more efficiently as data-level parallelism in the form of vector instructions
P284
The vector and scalar registers have a significant number of read and write ports to allow multiple simultaneous vector operations.
P285
primary components of the instruction set architecture of RV64V are the following:
- vector register
these ports will allow a high degree of overlap among vector operations to different vector registers, what does this mean ?
- Vector functional units
- Vector load/store unit
- A set of scalar registers
An innovation of RV64V is to associate a data type and data size with each vector register, rather than the normal approach of the instruction supplying that information
P286
P287
Reasons for dynamic register typing:
- many instructions are required for a conventional vector architecture that supports such variety. 2.
- dynamic typing also lets programs disable unused vector registers
As a consequence, enabled vector registers are allocated all the vector memory as long vectors. For example, assume we have 1024 bytes of vector memory, if 4 vector registers are enabled and they are type 64–bit floats, the processor would give each vector register 256 bytes or 256/8¼32 elements. This valiue is called the maximum vector length (mvl), which is set by the processor and cannot be changed by sofware
- A pleasant side effect of dynamic register typing is that the program can configure vector registers as disabled when they are not being used, so there is no need to save and restore them on
a context switch.
Our implementation of RV64V increases state a factor of 3: from 2 * 32 * 8 = 512 bytes to 2 * 32 * 1024 = 1536 bytes. !! i am good at arithmetic
- third benefit of dynamic register typing is that conversions between different size operands can be implicit depending on the configuration of the registers rather than as additional explicit conversion instructions
so what is vector register, is a vector of register or a just normal register whose size is 64bit
The vector-length register vl is used when the natural vector length is not equal to mvl, the vector-type register vctype records register types, and the predicate registers pi are used when loops involve IF statements.
P288
vsetdcfg 4*FP64 # Enable 4 DP FP vregs
fld f0,a # Load scalar a
vld v0,x5 # Load vector X
vmul v1,v0,f0 # Vector-scalar mult
vld v2,x6 # Load vector Y
vadd v3,v1,v2 # Vector-vector add
vst v3,x6 # Store the sum
vdisable # Disable vector regs
why vsetdcfg is
4 * PF64instead of32 * PF64
P289
When the compiler produces vector instructions for such a sequence, and the resulting code spends much of its time running in vector mode, the code is said to be vectorized or vectorizable. Loops can be vectorized when they do not have dependences between iterations of a loop, which are called loop-carried dependences
in the following two snippet, I still can not understand the vsetdcfg
Vector architects call forwarding of element dependent operations chaining, in that the dependent operations are “chained” together
P290
make a lot of assumption about how to calculate execution time and introduce some conception
The execution time of a sequence of vector operations primarily depends on three factors:
- the length of the operand vectors,
- structural hazards among the operations, and
- the data dependences.
To simplify the discussion of vector execution and vector performance, we use the notion of a convoy, which is the set of vector instructions that could potentially execute together
P291
Early implementations of chaining worked just like forwarding in scalar pipelining, but this restricted the timing of the source and destination instructions in the chain
how to understand the timing
Recent implementations use flexible chaining, which allows a vector instruction to chain to essentially any other active vector instruction, assuming that we don’t generate a structural hazard
any differences between early implement, we can implement both of them
To turn convoys into execution time, we need a metric to estimate the length of a convoy. It is called a chime, which is simply the unit of time taken to execute one convoy.
Thus a vector sequence that consists of m convoys executes in m chimes; for a vector length of n, for our simple RV64V implementation, this is approximately m * n clock cycles
vector !, vector !, so what is meaning of vector if exection of time is proportional to vection length
One source of overhead ignored inmeasuring chimes is any limitation on initiating multiple vector instructions in a single clock cycle
I can’t translate this into chinese, what do you mean by any limitation on initiating ?
Example
The first convoy starts with the first vld instruction. The vmul is dependent on the first vld, but chaining allows it to be in the same convoy
P292
The most important source of overhead ignored by the chime model is vector start-up time, which is the latency in clock cycles until the pipeline is full. The start-up time is principally determined by the pipelining latency of the vector functional unit
| Q | A |
|---|---|
| How can a vector processor execute a single vector faster than one element per clock cycle? | Multiple elements per clock cycle improve performance. |
| How does a vector processor handle programs where the vector lengths are not the same as the maximum vector length (mvl)? | Because most application vectors don’t match the architecture vector length, we need an efficient solution to this common case. |
| What happens when there is an IF statement inside the code to be vectorized? | More code can vectorize if we can efficiently handle conditional statements. |
| What does a vector processor need from the memory system ? | Without sufficient memory bandwidth, vector execution can be futile. |
| How does a vector processor handle multiple dimensional matrices? | This popular data structure must vectorize for vector architectures to do well. |
| How does a vector processor handle sparse matrices? | This popular data structure must vectorize also. |
| How do you program a vector computer? | Architectural innovations that are a mismatch to programming languages and their compilers may not get widespread use |
P293
Multiple Lanes: Beyond One Element per Clock Cycle
P294
P295
P296
Vector-Length Registers: Handling Loops Not Equal to 32
RISC-V has a better solution than a separate loop for strip mining
P297
Predicate Registers: Handling IF Statements in Vector Loops The presence of conditionals (IF statements) inside loops and the use of sparse matrices are two main reasons for lower levels of vectorization
Compiler writers use the term IF-conversion to transform an IF statement into a straight-line code sequence using conditional execution.
one difference between vector processors and GPUs is the way they handle conditional statements
P298
To maintain an initiation rate of one word fetched or stored per clock cycle, the memory system must be capable of producing or accepting this much data. Spreading accesses across multiple independent memory banks usually delivers the desired rate
P299
Memory Banks: Supplying Bandwidth for Vector Load/Store Units Most vector processors use memory banks, which allow several independent accesses rather than simple memory interleaving for three reasons:
- Many vector computers support many loads or stores per clock cycle, and the memory bank cycle time is usually several times larger than the processor cycle time. To support simultaneous accesses from multiple loads or stores, the memory system needs multiple banks and needs to be able to control the addresses to the banks independently.
- Most vector processors support the ability to load or store data words that are not sequential. In such cases, independent bank addressing, rather than interleaving, is required.
- Most vector computers support multiple processors sharing the same memory system, so each processor will be generating its own separate stream of addresses.
P300
Stride: Handling Multidimensional Arrays in Vector Architectures This distance separating elements to be gathered into a single vector register is called the stride.
Caches inherently deal with unit-stride data; increasing block size can help reduce miss rates for large scientific datasets with unit stride, but increasing block size can even have a negative effect for data that are accessed with nonunit strides.
Supporting strides greater than one complicates the memory system. Once we introduce nonunit strides, it becomes possible to request accesses from the same bank frequently.
!!! can not understand the formula at page 301, maybe a typo
P301
Gather-Scatter: Handling Sparse Matrices in Vector Architectures
P302
P303
Programming Vector Architectures It is this dialogue between the compiler and the programmer, with each side giving hints to the other on how to improve performance, that simplifies programming of vector computers
4.3 SIMD Instruction Set Extensions for Multimedia
P304
SIMD Multimedia Extensions started with the simple observation that many media applications operate on narrower data types than the 32-bit processors were optimized for
Unlike vector machines with large register files SIMD instructions tend to specify fewer operands and thus use much smaller register files
In contrast to vector architectures, which offer an elegant instruction set that is intended to be the target of a vectorizing compiler, SIMD extensions have three major omissions
- no vector length register
- no strided or gather/scatter data transfer instructions
- no mask register
P305
P306
SIMD Multimedia Extensions started with the simple observation that many media Given these weaknesses, why are multimedia SIMD extensions so popular?
The overarching issue, however, is that due the overiding importance of backwards binary compatability, once an architecture gets started on the SIMD path it’s very hard to get off it.
To get an idea about what multimedia instructions look like, assume we added a 256-bit SIMD multimedia instruction extension to RISC-V, tentatively called RVP for “packed.”
Oh, great, RISC-V doesn’t have SIMD Instruction
P307
Programming Multimedia SIMD Architectures
P308
The Roofline Visual Performance Model
skip, because it made me feel bad
Graphics Processing Units
P310
Thus the design of GPUs may make more sense when architects ask, given the hardware invested to do graphics well, how can we supplement it to improve the performance of a wider range of applications?
P311
The challenge for the GPU programmer is
- not simply getting good performance on the GPU,
- but also in coordinating the scheduling of computation on the system processor and the GPU and the transfer of data between system memory and GPU memory.
- Moreover, as we see will see later in this section, GPUs have virtually every type of parallelism that can be captured by the programming environment: multithreading, MIMD, SIMD, and even instruction-level
NVIDIA decided that the unifying theme of all these forms of parallelism is the CUDA Thread.
Using this lowest level of parallelism as the programming primitive, the compiler and the hardware can gang thousands of CUDA Threads together to utilize the various styles of parallelism within a GPU: multithreading, MIMD, SIMD, and instruction-level parallelism.
Therefore NVIDIA classifies the CUDA programming model as single instruction, multiple thread (SIMT).
For reasons we will soon see, these threads are blocked together and executed in groups of threads, called a Thread Block. We call the hardware that executes a whole block of threads a multithreaded SIMD Processor
We need just a few details before we can give an example of a CUDA program:
- To distinguish between functions for the GPU (device) and functions for the system processor (host), CUDA uses
__device__or__global__for the former and__host__for the latter. - CUDA variables declared with
__device__are allocated to the GPU Memory (see below), which is accessible by all multithreaded SIMD Processors. - The extended function call syntax for the function name that runs on the
GPU is
name < <<dimGrid, dimBlock>> > (… parameter list…)where
dimGridanddimBlockspecify the dimensions of the code (in Thread Blocks) and the dimensions of a block (in threads). - In addition to the identifier for blocks (blockIdx) and the identifier for each thread in a block (threadIdx), CUDA provides a keyword for the number of threads per block (blockDim), which comes from the dimBlock parameter in the preceding bullet.
P312
Different Thread Blocks cannot communicate directly, although they can coordinate using atomic memory operations in global memory.
As we will soon see, many GPU hardware concepts are not obvious in CUDA. Writing efficient GPU code requires that programmers think in terms of SIMD operations, even though the CUDA programming model looks like MIMD
Like many parallel systems, a compromise between productivity and performance is for CUDA to include intrinsics to give programmers explicit control over the hardware
P313
NVIDIA GPU Computational Structures One obstacle to understanding GPUs has been the jargon, with some terms even having misleading names.
ometimes, GPUs implement certain features in hardware that vector processors would implement in software. This difference is because vector processors have a scalar processor that can execute a software function
Unlike most vector architectures, GPUs also rely on multithreading within a single multithreaded SIMD Processor to hide memory latency
so, how vector architecture hide memory lantency ?
本站所有文章转发 CSDN 将按侵权追究法律责任,其它情况随意。