Documentation
¶
Overview ¶
Package timing provides an implementation of detailed Compute Unit modeling.
Index ¶
- type AllocStatus
- type BranchUnit
- type Builder
- type CUComponent
- type ComputeUnit
- type DecodeUnit
- func (du *DecodeUnit) AcceptWave(wave *wavefront.Wavefront, now akita.VTimeInSec)
- func (du *DecodeUnit) AddExecutionUnit(cuComponent CUComponent)
- func (du *DecodeUnit) CanAcceptWave() bool
- func (du *DecodeUnit) Flush()
- func (du *DecodeUnit) IsIdle() bool
- func (du *DecodeUnit) Run(now akita.VTimeInSec) bool
- type FetchArbiter
- type ISADebugger
- type InstFetchReqInfo
- type IssueArbiter
- type LDSUnit
- type RegisterAccess
- type RegisterFile
- type ResourceMask
- type SIMDUnit
- type ScalarMemAccessInfo
- type ScalarUnit
- type Scheduler
- type SchedulerImpl
- func (s *SchedulerImpl) DecodeNextInst(now akita.VTimeInSec) bool
- func (s *SchedulerImpl) DoFetch(now akita.VTimeInSec) bool
- func (s *SchedulerImpl) DoIssue(now akita.VTimeInSec) bool
- func (s *SchedulerImpl) EvaluateInternalInst(now akita.VTimeInSec) bool
- func (s *SchedulerImpl) Flush()
- func (s *SchedulerImpl) Pause()
- func (s *SchedulerImpl) Resume()
- func (s *SchedulerImpl) Run(now akita.VTimeInSec) bool
- type ScratchpadPreparer
- type ScratchpadPreparerImpl
- type SimpleRegisterFile
- type VectorMemAccessInfo
- type VectorMemoryUnit
- type WGMapper
- type WGMapperImpl
- type WavefrontPool
- type WfArbiter
- type WfCompletionEvent
- type WfDispatchEvent
- type WfDispatchInfo
- type WfDispatcher
- type WfDispatcherImpl
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type AllocStatus ¶
type AllocStatus byte
AllocStatus represents the allocation status of SGPRs, VGPRs, or LDS units
const ( AllocStatusFree AllocStatus = iota AllocStatusToReserve // A value that is used for reservation caculation AllocStatusReserved // Work-Group mapped, but wavefront not dispatched AllocStatusUsed // Currently in use )
A list of possible status for CU binded storage allocation
type BranchUnit ¶
type BranchUnit struct {
// contains filtered or unexported fields
}
A BranchUnit performs branch operations
func NewBranchUnit ¶
func NewBranchUnit( cu *ComputeUnit, scratchpadPreparer ScratchpadPreparer, alu emu.ALU, ) *BranchUnit
NewBranchUnit creates a new branch unit, injecting the dependency of the compute unit.
func (*BranchUnit) AcceptWave ¶
func (u *BranchUnit) AcceptWave( wave *wavefront.Wavefront, now akita.VTimeInSec, )
AcceptWave moves one wavefront into the read buffer of the branch unit
func (*BranchUnit) CanAcceptWave ¶
func (u *BranchUnit) CanAcceptWave() bool
CanAcceptWave checks if the buffer of the read stage is occupied or not
func (*BranchUnit) Flush ¶
func (u *BranchUnit) Flush()
func (*BranchUnit) IsIdle ¶
func (u *BranchUnit) IsIdle() bool
func (*BranchUnit) Run ¶
func (u *BranchUnit) Run(now akita.VTimeInSec) bool
Run executes three pipeline stages that are controlled by the BranchUnit
type Builder ¶
type Builder struct { Engine akita.Engine Freq akita.Freq CUName string SIMDCount int VGPRCount []int SGPRCount int Decoder emu.Decoder ScratchpadPreparer ScratchpadPreparer ALU emu.ALU InstMem akita.Port ScalarMem akita.Port VectorMemModules cache.LowModuleFinder ConnToInstMem akita.Connection ConnToScalarMem akita.Connection ConnToVectorMem akita.Connection // contains filtered or unexported fields }
A Builder can construct a fully functional ComputeUnit to the outside world. It simplify the compute unit building process.
func (*Builder) Build ¶
func (b *Builder) Build() *ComputeUnit
Build returns a newly constructed compute unit according to the configuration
type CUComponent ¶
type CUComponent interface { CanAcceptWave() bool AcceptWave(wave *wavefront.Wavefront, now akita.VTimeInSec) Run(now akita.VTimeInSec) bool IsIdle() bool Flush() }
A CUComponent is an element installed in the compute unit
type ComputeUnit ¶
type ComputeUnit struct { *akita.TickingComponent WGMapper WGMapper WfDispatcher WfDispatcher Decoder emu.Decoder WfPools []*WavefrontPool WfToDispatch map[*kernels.Wavefront]*WfDispatchInfo InFlightInstFetch []*InstFetchReqInfo InFlightScalarMemAccess []*ScalarMemAccessInfo InFlightVectorMemAccess []VectorMemAccessInfo Scheduler Scheduler BranchUnit CUComponent VectorMemDecoder CUComponent VectorMemUnit CUComponent ScalarDecoder CUComponent VectorDecoder CUComponent LDSDecoder CUComponent ScalarUnit CUComponent SIMDUnit []CUComponent LDSUnit CUComponent SRegFile RegisterFile VRegFile []RegisterFile InstMem akita.Port ScalarMem akita.Port VectorMemModules cache.LowModuleFinder ToACE akita.Port ToInstMem akita.Port ToScalarMem akita.Port ToVectorMem akita.Port ToCP akita.Port // contains filtered or unexported fields }
A ComputeUnit in the timing package provides a detailed and accurate simulation of a GCN3 ComputeUnit
func NewComputeUnit ¶
func NewComputeUnit( name string, engine akita.Engine, ) *ComputeUnit
NewComputeUnit returns a newly constructed compute unit
func (*ComputeUnit) Handle ¶
func (cu *ComputeUnit) Handle(evt akita.Event) error
Handle processes that events that are scheduled on the ComputeUnit
func (*ComputeUnit) Tick ¶
func (cu *ComputeUnit) Tick(now akita.VTimeInSec) bool
func (*ComputeUnit) UpdatePCAndSetReady ¶
func (cu *ComputeUnit) UpdatePCAndSetReady(wf *wavefront.Wavefront)
type DecodeUnit ¶
type DecodeUnit struct { ExecUnits []CUComponent // Execution units, index by SIMD number // contains filtered or unexported fields }
A DecodeUnit is any type of decode unit that takes one cycle to decode
func NewDecodeUnit ¶
func NewDecodeUnit(cu *ComputeUnit) *DecodeUnit
NewDecodeUnit creates a new decode unit
func (*DecodeUnit) AcceptWave ¶
func (du *DecodeUnit) AcceptWave( wave *wavefront.Wavefront, now akita.VTimeInSec, )
AcceptWave takes a wavefront and decode the instruction in the next cycle
func (*DecodeUnit) AddExecutionUnit ¶
func (du *DecodeUnit) AddExecutionUnit(cuComponent CUComponent)
AddExecutionUnit registers an executions unit to the decode unit, so that the decode unit knows where to send the instruction to after decoding. This function has to be called in the order of SIMD number.
func (*DecodeUnit) CanAcceptWave ¶
func (du *DecodeUnit) CanAcceptWave() bool
CanAcceptWave checks if the DecodeUnit is ready to decode another instruction
func (*DecodeUnit) Flush ¶
func (du *DecodeUnit) Flush()
func (*DecodeUnit) IsIdle ¶
func (du *DecodeUnit) IsIdle() bool
func (*DecodeUnit) Run ¶
func (du *DecodeUnit) Run(now akita.VTimeInSec) bool
Run decodes the instruction and sends the instruction to the next pipeline stage
type FetchArbiter ¶
type FetchArbiter struct {
InstBufByteSize int
}
A FetchArbiter can decide which wavefront in a scheduler can fetch instructions
func (*FetchArbiter) Arbitrate ¶
func (a *FetchArbiter) Arbitrate( wfPools []*WavefrontPool, ) []*wavefront.Wavefront
Arbitrate decide which wavefront can fetch the next instruction
type ISADebugger ¶
type ISADebugger struct { akita.LogHookBase // contains filtered or unexported fields }
ISADebugger is a logger hook that can dump the wavefront status after each instruction execution
func NewISADebugger ¶
func NewISADebugger(logger *log.Logger) *ISADebugger
NewISADebugger creates a new ISADebugger.
func (*ISADebugger) Func ¶
func (d *ISADebugger) Func( ctx akita.HookCtx, )
Func defines the action that the ISADebugger takes
type InstFetchReqInfo ¶
type IssueArbiter ¶
type IssueArbiter struct {
// contains filtered or unexported fields
}
An IssueArbiter decides which wavefront can issue instruction
func NewIssueArbiter ¶
func NewIssueArbiter() *IssueArbiter
NewIssueArbiter returns a newly created IssueArbiter
func (*IssueArbiter) Arbitrate ¶
func (a *IssueArbiter) Arbitrate( wfPools []*WavefrontPool, ) []*wavefront.Wavefront
Arbitrate will take a round-robin fashion at SIMD level. For wavefronts in each SIMD, oldest first.
type LDSUnit ¶
type LDSUnit struct {
// contains filtered or unexported fields
}
A LDSUnit performs Scalar operations
func NewLDSUnit ¶
func NewLDSUnit( cu *ComputeUnit, scratchpadPreparer ScratchpadPreparer, alu emu.ALU, ) *LDSUnit
NewLDSUnit creates a new Scalar unit, injecting the dependency of the compute unit.
func (*LDSUnit) AcceptWave ¶
func (u *LDSUnit) AcceptWave(wave *wavefront.Wavefront, now akita.VTimeInSec)
AcceptWave moves one wavefront into the read buffer of the Scalar unit
func (*LDSUnit) CanAcceptWave ¶
CanAcceptWave checks if the buffer of the read stage is occupied or not
type RegisterAccess ¶
type RegisterAccess struct { Time akita.VTimeInSec Reg *insts.Reg RegCount int LaneID int WaveOffset int Data []byte OK bool }
A RegisterAccess is an incidence of reading or writing the register
type RegisterFile ¶
type RegisterFile interface { Read(access RegisterAccess) Write(access RegisterAccess) }
A RegisterFile provides the communication interface for a set of registers.
type ResourceMask ¶
type ResourceMask struct {
// contains filtered or unexported fields
}
A ResourceMask is data structure to mask the status of some resources
func NewResourceMask ¶
func NewResourceMask(size int) *ResourceMask
NewResourceMask returns a newly created ResourceMask with a given size.
func (*ResourceMask) ConvertStatus ¶
func (m *ResourceMask) ConvertStatus(from, to AllocStatus)
ConvertStatus change all the element of one status to another
func (*ResourceMask) NextRegion ¶
func (m *ResourceMask) NextRegion( length int, statusReq AllocStatus, ) (int, bool)
NextRegion finds a region that is masked by the resourceMask in the state define by statusReq. This function returns the offset of the starting point of the region. It also returns a boolean value that tells if a region is found
func (*ResourceMask) SetStatus ¶
func (m *ResourceMask) SetStatus(offset, length int, status AllocStatus)
SetStatus alters the status from the position of offset to offset + length
func (*ResourceMask) StatusCount ¶
func (m *ResourceMask) StatusCount(status AllocStatus) int
StatusCount returns the number of element that is in the target status
type SIMDUnit ¶
type SIMDUnit struct { akita.HookableBase NumSinglePrecisionUnit int // contains filtered or unexported fields }
A SIMDUnit performs branch operations
func NewSIMDUnit ¶
func NewSIMDUnit( cu *ComputeUnit, name string, scratchpadPreparer ScratchpadPreparer, alu emu.ALU, ) *SIMDUnit
NewSIMDUnit creates a new branch unit, injecting the dependency of the compute unit.
func (*SIMDUnit) AcceptWave ¶
func (u *SIMDUnit) AcceptWave(wave *wavefront.Wavefront, now akita.VTimeInSec)
AcceptWave moves one wavefront into the read buffer of the branch unit
func (*SIMDUnit) CanAcceptWave ¶
CanAcceptWave checks if the buffer of the read stage is occupied or not
type ScalarMemAccessInfo ¶
type ScalarUnit ¶
type ScalarUnit struct {
// contains filtered or unexported fields
}
A ScalarUnit performs Scalar operations
func NewScalarUnit ¶
func NewScalarUnit( cu *ComputeUnit, scratchpadPreparer ScratchpadPreparer, alu emu.ALU, ) *ScalarUnit
NewScalarUnit creates a new Scalar unit, injecting the dependency of the compute unit.
func (*ScalarUnit) AcceptWave ¶
func (u *ScalarUnit) AcceptWave(wave *wavefront.Wavefront, now akita.VTimeInSec)
AcceptWave moves one wavefront into the read buffer of the Scalar unit
func (*ScalarUnit) CanAcceptWave ¶
func (u *ScalarUnit) CanAcceptWave() bool
CanAcceptWave checks if the buffer of the read stage is occupied or not
func (*ScalarUnit) Flush ¶
func (u *ScalarUnit) Flush()
func (*ScalarUnit) IsIdle ¶
func (u *ScalarUnit) IsIdle() bool
CanAcceptWave checks if the buffer of the read stage is occupied or not
func (*ScalarUnit) Run ¶
func (u *ScalarUnit) Run(now akita.VTimeInSec) bool
Run executes three pipeline stages that are controlled by the ScalarUnit
type Scheduler ¶
type Scheduler interface { Run(now akita.VTimeInSec) bool Pause() Resume() Flush() }
type SchedulerImpl ¶
type SchedulerImpl struct {
// contains filtered or unexported fields
}
A Scheduler is the controlling unit of a compute unit. It decides which wavefront to fetch and to issue.
func NewScheduler ¶
func NewScheduler( cu *ComputeUnit, fetchArbiter WfArbiter, issueArbiter WfArbiter, ) *SchedulerImpl
NewScheduler returns a newly created scheduler, injecting dependency of the compute unit, the fetch arbiter, and the issue arbiter.
func (*SchedulerImpl) DecodeNextInst ¶
func (s *SchedulerImpl) DecodeNextInst(now akita.VTimeInSec) bool
func (*SchedulerImpl) DoFetch ¶
func (s *SchedulerImpl) DoFetch(now akita.VTimeInSec) bool
DoFetch function of the scheduler will fetch instructions from the instruction memory
func (*SchedulerImpl) DoIssue ¶
func (s *SchedulerImpl) DoIssue(now akita.VTimeInSec) bool
DoIssue function of the scheduler issues fetched instruction to the decoding units
func (*SchedulerImpl) EvaluateInternalInst ¶
func (s *SchedulerImpl) EvaluateInternalInst(now akita.VTimeInSec) bool
EvaluateInternalInst updates the status of the instruction being executed in the scheduler.
func (*SchedulerImpl) Flush ¶
func (s *SchedulerImpl) Flush()
func (*SchedulerImpl) Pause ¶
func (s *SchedulerImpl) Pause()
func (*SchedulerImpl) Resume ¶
func (s *SchedulerImpl) Resume()
func (*SchedulerImpl) Run ¶
func (s *SchedulerImpl) Run(now akita.VTimeInSec) bool
type ScratchpadPreparer ¶
type ScratchpadPreparer interface { Prepare(instEmuState emu.InstEmuState, wf *wavefront.Wavefront) Commit(instEmuState emu.InstEmuState, wf *wavefront.Wavefront) }
type ScratchpadPreparerImpl ¶
type ScratchpadPreparerImpl struct {
// contains filtered or unexported fields
}
ScratchpadPreparerImpl reads and write registers for the emulator
func NewScratchpadPreparerImpl ¶
func NewScratchpadPreparerImpl(cu *ComputeUnit) *ScratchpadPreparerImpl
NewScratchpadPreparerImpl returns a newly created ScratchpadPreparerImpl, injecting the dependency of the RegInterface.
func (*ScratchpadPreparerImpl) Commit ¶
func (p *ScratchpadPreparerImpl) Commit( instEmuState emu.InstEmuState, wf *wavefront.Wavefront, )
Commit write to the register file according to the scratchpad layout
func (*ScratchpadPreparerImpl) Prepare ¶
func (p *ScratchpadPreparerImpl) Prepare( instEmuState emu.InstEmuState, wf *wavefront.Wavefront, )
Prepare read from the register file and sets the scratchpad layout
type SimpleRegisterFile ¶
type SimpleRegisterFile struct { // In vector register, each lane can have up-to 256 VGPRs. Then the offset // difference from v0 lane 0 to v0 lane 1 is 256*4 = 1024B. Field // ByteSizePerLane should be set to 1024 in vector registers. ByteSizePerLane int // contains filtered or unexported fields }
A SimpleRegisterFile is a Register file that can always read and write registers immediately
func NewSimpleRegisterFile ¶
func NewSimpleRegisterFile( byteSize uint64, byteSizePerLane int, ) *SimpleRegisterFile
NewSimpleRegisterFile creates and returns a new SimpleRegisterFile
func (*SimpleRegisterFile) Read ¶
func (r *SimpleRegisterFile) Read(access RegisterAccess)
func (*SimpleRegisterFile) Write ¶
func (r *SimpleRegisterFile) Write(access RegisterAccess)
type VectorMemAccessInfo ¶
type VectorMemoryUnit ¶
type VectorMemoryUnit struct { SendBuf []mem.AccessReq SendBufSize int AddrCoalescingLatency int AddrCoalescingCycleLeft int // contains filtered or unexported fields }
A VectorMemoryUnit performs Scalar operations
func NewVectorMemoryUnit ¶
func NewVectorMemoryUnit( cu *ComputeUnit, scratchpadPreparer ScratchpadPreparer, coalescer coalescer, ) *VectorMemoryUnit
NewVectorMemoryUnit creates a new Scalar unit, injecting the dependency of the compute unit.
func (*VectorMemoryUnit) AcceptWave ¶
func (u *VectorMemoryUnit) AcceptWave(wave *wavefront.Wavefront, now akita.VTimeInSec)
AcceptWave moves one wavefront into the read buffer of the Scalar unit
func (*VectorMemoryUnit) CanAcceptWave ¶
func (u *VectorMemoryUnit) CanAcceptWave() bool
CanAcceptWave checks if the buffer of the read stage is occupied or not
func (*VectorMemoryUnit) Flush ¶
func (u *VectorMemoryUnit) Flush()
func (*VectorMemoryUnit) IsIdle ¶
func (u *VectorMemoryUnit) IsIdle() bool
IsIdle moves one wavefront into the read buffer of the Scalar unit
func (*VectorMemoryUnit) Run ¶
func (u *VectorMemoryUnit) Run(now akita.VTimeInSec) bool
Run executes three pipeline stages that are controlled by the VectorMemoryUnit
type WGMapper ¶
WGMapper defines the behavior of how a workgroup is mapped in the compute unit.
It is responsible for allocating SIMD number, VGPRs offset, SGPRs offset and LDS offset for each wavefront in the workgroup. A WGMapper is not a component and we assume the mapping process is done within a cycle
type WGMapperImpl ¶
type WGMapperImpl struct { NumWfPool int WfPoolFreeCount []int SGprCount int SGprGranularity int SGprMask *ResourceMask VGprCount []int VGprGranularity int VGprMask []*ResourceMask LDSByteSize int LDSGranularity int LDSMask *ResourceMask // contains filtered or unexported fields }
WGMapperImpl is a sub-component of scheduler. It is responsible for allocate and reserve resources for the incoming MapWgReq.
func NewWGMapper ¶
func NewWGMapper(cu *ComputeUnit, numWfPool int) *WGMapperImpl
NewWGMapper returns a newly created WgMapper with default compute unit setting
func (*WGMapperImpl) MapWG ¶
func (m *WGMapperImpl) MapWG(req *gcn3.MapWGReq) bool
MapWG uses a first fit algorithm to allocate SGPR, VGPR, and LDS resources. In terms of SIMD selection, it uses a round robin policy.
func (*WGMapperImpl) SetWfPoolSizes ¶
func (m *WGMapperImpl) SetWfPoolSizes(numWfs []int)
SetWfPoolSizes updates the number of WfPools and it number of wavefronts that a wavefront pool can handle.
func (*WGMapperImpl) UnmapWG ¶
func (m *WGMapperImpl) UnmapWG(wg *wavefront.WorkGroup)
UnmapWG will remove all the resource reservation of a work-group
type WavefrontPool ¶
type WavefrontPool struct { Capacity int VRegFile akita.Component // contains filtered or unexported fields }
A WavefrontPool holds the wavefronts that will be scheduled in one SIMD unit
func NewWavefrontPool ¶
func NewWavefrontPool(capacity int) *WavefrontPool
NewWavefrontPool creates and returns a new WavefrontPool
func (*WavefrontPool) AddWf ¶
func (wfp *WavefrontPool) AddWf(wf *wavefront.Wavefront)
AddWf will add an wavefront to the wavefront pool
func (*WavefrontPool) Availability ¶
func (wfp *WavefrontPool) Availability() int
Availability returns the number of extra Wavefront that the wavefront pool can hold
func (*WavefrontPool) RemoveWf ¶
func (wfp *WavefrontPool) RemoveWf(wf *wavefront.Wavefront)
RemoveWf removes a wavefront from a wavefront pool
type WfArbiter ¶
type WfArbiter interface {
Arbitrate(wfpools []*WavefrontPool) []*wavefront.Wavefront
}
An WfArbiter can decide which wavefront can take action, in a list of wavefront pools
type WfCompletionEvent ¶
A WfCompletionEvent marks the completion of a wavefront
func NewWfCompletionEvent ¶
func NewWfCompletionEvent( time akita.VTimeInSec, handler akita.Handler, wf *wavefront.Wavefront, ) *WfCompletionEvent
NewWfCompletionEvent returns a newly constructed WfCompleteEvent
type WfDispatchEvent ¶
type WfDispatchEvent struct { *akita.EventBase ManagedWf *wavefront.Wavefront IsLastInWG bool MapWGReq *gcn3.MapWGReq }
WfDispatchEvent is the event that the dispatcher dispatches a wavefront
func NewWfDispatchEvent ¶
func NewWfDispatchEvent( t akita.VTimeInSec, handler akita.Handler, Wf *wavefront.Wavefront, ) *WfDispatchEvent
NewWfDispatchEvent creates a new WfDispatchCompletionEvent
type WfDispatchInfo ¶
type WfDispatchInfo struct { Wavefront *kernels.Wavefront SIMDID int VGPROffset int SGPROffset int LDSOffset int }
WfDispatchInfo preservers the information from a work-group mapping to guarantee a wavefront to be dispatching to its designated location
type WfDispatcher ¶
type WfDispatcher interface {
DispatchWf(now akita.VTimeInSec, wf *wavefront.Wavefront)
}
A WfDispatcher initialize wavefronts
type WfDispatcherImpl ¶
type WfDispatcherImpl struct { Latency int // contains filtered or unexported fields }
A WfDispatcherImpl will register the wavefront in wavefront pool and initialize all the registers
func NewWfDispatcher ¶
func NewWfDispatcher(cu *ComputeUnit) *WfDispatcherImpl
NewWfDispatcher creates a default WfDispatcher
func (*WfDispatcherImpl) DispatchWf ¶
func (d *WfDispatcherImpl) DispatchWf( now akita.VTimeInSec, wf *wavefront.Wavefront, )
DispatchWf starts or continues a wavefront dispatching process.
Source Files
¶
- branchunit.go
- coalescer.go
- computeunit.go
- cubuilder.go
- cucomponent.go
- decodeunit.go
- defaultcoalescer.go
- doc.go
- fetcharbiter.go
- isa_debugger.go
- issuearbiter.go
- ldsunit.go
- memaccessinfo.go
- registerfile.go
- resourcemask.go
- scalarunit.go
- scheduler.go
- scratchpadpreparer.go
- simdunit.go
- vectormemoryunit.go
- wavefrontpool.go
- wfarbiter.go
- wfcompletionevent.go
- wfdispatcher.go
- wfdispatchevent.go
- wfdispatchinfo.go
- wgmapper.go
Directories
¶
Path | Synopsis |
---|---|
caches
|
|
l1v
Package l1v provides a GCN3 GPU L1 cache implementation.
|
Package l1v provides a GCN3 GPU L1 cache implementation. |
Package mock_timing is a generated GoMock package.
|
Package mock_timing is a generated GoMock package. |
Package pipelines defines a pipeline timing model.
|
Package pipelines defines a pipeline timing model. |
Package wavefront defines concepts related to a wavefront.
|
Package wavefront defines concepts related to a wavefront. |