gem5: more analysis

This commit is contained in:
Ciro Santilli 六四事件 法轮功
2020-02-28 00:00:02 +00:00
parent 44ac89eb72
commit 1f007b2004
2 changed files with 266 additions and 97 deletions

View File

@@ -12934,14 +12934,16 @@ Not all times need to have an associated event: if a given time has no events, g
Important examples of events include: Important examples of events include:
* CPU ticks * CPU ticks
* TODO peripherals and memory * peripherals and memory
At the beginning of simulation, gem5 sets up exactly two events: At <<gem5-event-queue-atomicsimplecpu-syscall-emulation-freestanding-example-analysis>> we see for example that at the beginning of an <<gem5-basesimplecpu,AtomicCPU>> simulation, gem5 sets up exactly two events:
* the first CPU cycle * the first CPU cycle
* one exit event at the end of time which triggers <<gem5-simulate-limit-reached>> * one exit event at the end of time which triggers <<gem5-simulate-limit-reached>>
Tick events then get triggered one by one as simulation progresses, in addition to any other system events. Then, at the end of the callback of one tick event, another tick is scheduled.
And so the simulation progresses tick by tick, until an exit event happens.
The `EventQueue` class has one awesome `dump()` function that prints a human friendly representation of the queue, and can be easily called from GDB. TODO example. The `EventQueue` class has one awesome `dump()` function that prints a human friendly representation of the queue, and can be easily called from GDB. TODO example.
@@ -13075,6 +13077,12 @@ def instantiate(ckpt_dir=None):
for obj in root.descendants(): obj.initState() for obj in root.descendants(): obj.initState()
.... ....
and this gets called from the toplevel Python scripts e.g. forsefpy `configs/common/Simulation.py` does:
....
m5.instantiate(checkpoint_dir)
....
As we can see, `initState` is just one stage of generic `SimObject` initialization. `root.descendants()` goes over the entire `SimObject` tree calling `initState()`. As we can see, `initState` is just one stage of generic `SimObject` initialization. `root.descendants()` goes over the entire `SimObject` tree calling `initState()`.
Finally, we see that `initState` is part of the `SimObject` C++ API: Finally, we see that `initState` is part of the `SimObject` C++ API:
@@ -13207,15 +13215,16 @@ TODO: analyze better what each of the memory event mean. For now, we have just c
./run \ ./run \
--arch aarch64 \ --arch aarch64 \
--emulator gem5 \ --emulator gem5 \
--gem5-build-type gem5 \
--userland userland/arch/aarch64/freestanding/linux/hello.S \ --userland userland/arch/aarch64/freestanding/linux/hello.S \
--trace Event,ExecAll \ --trace Event,ExecAll,FmtFlag \
--trace-stdout \ --trace-stdout \
-- \ -- \
--cpu-type TimingSimpleCPU \ --cpu-type TimingSimpleCPU \
; ;
.... ....
As of LKMC 9bfbff244d713de40e5686bd370eadb20cf78c7b + 1 the log is now much more complex. As of LKMC 78ce2dabe18ef1d87dc435e5bc9369ce82e8d6d2 gem5 12c917de54145d2d50260035ba7fa614e25317a3 the log is now much more complex.
Here is an abridged version with: Here is an abridged version with:
@@ -13225,38 +13234,85 @@ Here is an abridged version with:
because all that happens in between is exactly the same as the first two instructions and therefore boring: because all that happens in between is exactly the same as the first two instructions and therefore boring:
.... ....
0: system.cpu.wrapped_function_event: EventFunctionWrapped event scheduled @ 0 0: Event: system.cpu.wrapped_function_event: EventFunctionWrapped 43 scheduled @ 0
**** REAL SIMULATION **** **** REAL SIMULATION ****
0: system.mem_ctrls_0.wrapped_function_event: EventFunctionWrapped event scheduled @ 7786250 0: Event: system.mem_ctrls_0.wrapped_function_event: EventFunctionWrapped 14 scheduled @ 7786250
0: system.mem_ctrls_1.wrapped_function_event: EventFunctionWrapped event scheduled @ 7786250 0: Event: system.mem_ctrls_1.wrapped_function_event: EventFunctionWrapped 20 scheduled @ 7786250
0: Event_74: generic event scheduled @ 0 0: Event: Event_74: generic 74 scheduled @ 0
info: Entering event queue @ 0. Starting simulation... info: Entering event queue @ 0. Starting simulation...
0: Event_74: generic event rescheduled @ 18446744073709551615 0: Event: Event_74: generic 74 rescheduled @ 18446744073709551615
0: system.mem_ctrls.wrapped_function_event: EventFunctionWrapped event scheduled @ 0
0: system.membus.reqLayer0.wrapped_function_event: EventFunctionWrapped event scheduled @ 1000 0: Event: system.cpu.wrapped_function_event: EventFunctionWrapped 43 executed @ 0
0: system.mem_ctrls_0.wrapped_function_event: EventFunctionWrapped event scheduled @ 0 0: Event: system.mem_ctrls.wrapped_function_event: EventFunctionWrapped 9 scheduled @ 0
0: system.mem_ctrls.wrapped_function_event: EventFunctionWrapped event scheduled @ 46250 0: Event: system.membus.reqLayer0.wrapped_function_event: EventFunctionWrapped 60 scheduled @ 1000
0: system.mem_ctrls.wrapped_function_event: EventFunctionWrapped event scheduled @ 5000
0: system.mem_ctrls_0.wrapped_function_event: EventFunctionWrapped event scheduled @ 0 0: Event: system.mem_ctrls.wrapped_function_event: EventFunctionWrapped 9 executed @ 0
46250: system.mem_ctrls.port-RespPacketQueue.wrapped_function_event: EventFunctionWrapped event scheduled @ 74250 0: Event: system.mem_ctrls_0.wrapped_function_event: EventFunctionWrapped 12 scheduled @ 0
74250: system.membus.slave[1]-RespPacketQueue.wrapped_function_event: EventFunctionWrapped event scheduled @ 77000 0: Event: system.mem_ctrls.wrapped_function_event: EventFunctionWrapped 10 scheduled @ 46250
74250: system.membus.respLayer1.wrapped_function_event: EventFunctionWrapped event scheduled @ 77000 0: Event: system.mem_ctrls.wrapped_function_event: EventFunctionWrapped 9 scheduled @ 5000
77000: Event_40: Timing CPU icache tick event scheduled @ 77000
77000: system.cpu A0 T0 : @asm_main_after_prologue : movz x0, #1, #0 : IntAlu : D=0x0000000000000001 flags=(IsInteger) 0: Event: system.mem_ctrls_0.wrapped_function_event: EventFunctionWrapped 12 executed @ 0
77000: system.mem_ctrls.wrapped_function_event: EventFunctionWrapped event scheduled @ 77000 0: Event: system.mem_ctrls_0.wrapped_function_event: EventFunctionWrapped 15 scheduled @ 0
77000: system.membus.reqLayer0.wrapped_function_event: EventFunctionWrapped event scheduled @ 78000
77000: system.mem_ctrls.wrapped_function_event: EventFunctionWrapped event scheduled @ 95750 0: Event: system.mem_ctrls_0.wrapped_function_event: EventFunctionWrapped 15 executed @ 0
77000: system.mem_ctrls.wrapped_function_event: EventFunctionWrapped event scheduled @ 77000
95750: system.mem_ctrls.port-RespPacketQueue.wrapped_function_event: EventFunctionWrapped event scheduled @ 123750 1000: Event: system.membus.reqLayer0.wrapped_function_event: EventFunctionWrapped 60 executed @ 1000
123750: system.membus.slave[1]-RespPacketQueue.wrapped_function_event: EventFunctionWrapped event scheduled @ 126000
123750: system.membus.respLayer1.wrapped_function_event: EventFunctionWrapped event scheduled @ 126000 5000: Event: system.mem_ctrls.wrapped_function_event: EventFunctionWrapped 9 executed @ 5000
126000: Event_40: Timing CPU icache tick event scheduled @ 126000
[...] 46250: Event: system.mem_ctrls.wrapped_function_event: EventFunctionWrapped 10 executed @ 46250
469000: system.cpu A0 T0 : @asm_main_after_prologue+28 : svc #0x0 : IntAlu : flags=(IsSerializeAfter|IsNonSpeculative|IsSyscall) 46250: Event: system.mem_ctrls.port-RespPacketQueue.wrapped_function_event: EventFunctionWrapped 8 scheduled @ 74250
469000: Event_75: generic event scheduled @ 469000
74250: Event: system.mem_ctrls.port-RespPacketQueue.wrapped_function_event: EventFunctionWrapped 8 executed @ 74250
74250: Event: system.membus.slave[1]-RespPacketQueue.wrapped_function_event: EventFunctionWrapped 64 scheduled @ 77000
74250: Event: system.membus.respLayer1.wrapped_function_event: EventFunctionWrapped 65 scheduled @ 77000
77000: Event: system.membus.respLayer1.wrapped_function_event: EventFunctionWrapped 65 executed @ 77000
77000: Event: system.membus.slave[1]-RespPacketQueue.wrapped_function_event: EventFunctionWrapped 64 executed @ 77000
77000: Event: Event_40: Timing CPU icache tick 40 scheduled @ 77000
77000: Event: Event_40: Timing CPU icache tick 40 executed @ 77000
77000: ExecEnable: system.cpu: A0 T0 : @asm_main_after_prologue : movz x0, #1, #0 : IntAlu : D=0x0000000000000001 flags=(IsInteger)
77000: Event: system.mem_ctrls.wrapped_function_event: EventFunctionWrapped 9 scheduled @ 77000
77000: Event: system.membus.reqLayer0.wrapped_function_event: EventFunctionWrapped 60 scheduled @ 78000
77000: Event: system.mem_ctrls.wrapped_function_event: EventFunctionWrapped 9 executed @ 77000
77000: Event: system.mem_ctrls.wrapped_function_event: EventFunctionWrapped 10 scheduled @ 95750
77000: Event: system.mem_ctrls.wrapped_function_event: EventFunctionWrapped 9 scheduled @ 77000
77000: Event: system.mem_ctrls.wrapped_function_event: EventFunctionWrapped 9 executed @ 77000
78000: Event: system.membus.reqLayer0.wrapped_function_event: EventFunctionWrapped 60 executed @ 78000
95750: Event: system.mem_ctrls.wrapped_function_event: EventFunctionWrapped 10 executed @ 95750
95750: Event: system.mem_ctrls.port-RespPacketQueue.wrapped_function_event: EventFunctionWrapped 8 scheduled @ 123750
123750: Event: system.mem_ctrls.port-RespPacketQueue.wrapped_function_event: EventFunctionWrapped 8 executed @ 123750
123750: Event: system.membus.slave[1]-RespPacketQueue.wrapped_function_event: EventFunctionWrapped 64 scheduled @ 126000
123750: Event: system.membus.respLayer1.wrapped_function_event: EventFunctionWrapped 65 scheduled @ 126000
126000: Event: system.membus.respLayer1.wrapped_function_event: EventFunctionWrapped 65 executed @ 126000
126000: Event: system.membus.slave[1]-RespPacketQueue.wrapped_function_event: EventFunctionWrapped 64 executed @ 126000
126000: Event: Event_40: Timing CPU icache tick 40 scheduled @ 126000
126000: Event: Event_40: Timing CPU icache tick 40 executed @ 126000
126000: ExecEnable: system.cpu: A0 T0 : @asm_main_after_prologue+4 : adr x1, #28 : IntAlu : D=0x0000000000400098 flags=(IsInteger)
126000: Event: system.mem_ctrls.wrapped_function_event: EventFunctionWrapped 9 scheduled @ 126000
126000: Event: system.membus.reqLayer0.wrapped_function_event: EventFunctionWrapped 60 scheduled @ 127000
126000: Event: system.mem_ctrls.wrapped_function_event: EventFunctionWrapped 9 executed @ 126000
126000: Event: system.mem_ctrls.wrapped_function_event: EventFunctionWrapped 10 scheduled @ 144750
126000: Event: system.mem_ctrls.wrapped_function_event: EventFunctionWrapped 9 scheduled @ 126000
126000: Event: system.mem_ctrls.wrapped_function_event: EventFunctionWrapped 9 executed @ 126000
[...]
469000: ExecEnable: system.cpu: A0 T0 : @asm_main_after_prologue+28 : svc #0x0 : IntAlu : flags=(IsSerializeAfter|IsNonSpeculative|IsSyscall)
469000: Event: Event_75: generic 75 scheduled @ 469000
469000: Event: Event_75: generic 75 executed @ 469000
.... ....
`0: system.cpu.wrapped_function_event` schedule the initial tick, much like for for `AtomicSimpleCPU`. This time however, it is not a tick, but rather a fetch event that gets scheduled: The first event scheduled:
....
0: Event: system.cpu.wrapped_function_event: EventFunctionWrapped 43 scheduled @ 0
....
schedules the initial tick, much like for for `AtomicSimpleCPU`.
This time however, it is not a tick, but rather a fetch event that gets scheduled:
.... ....
TimingSimpleCPU::activateContext(ThreadID thread_num) TimingSimpleCPU::activateContext(ThreadID thread_num)
@@ -13274,11 +13330,36 @@ TimingSimpleCPU::activateContext(ThreadID thread_num)
schedule(fetchEvent, clockEdge(Cycles(0))); schedule(fetchEvent, clockEdge(Cycles(0)));
.... ....
and just like for `AtomicSimpleCPU` it comes from the `initState` call:
....
EventManager::schedule
TimingSimpleCPU::activateContext
SimpleThread::activate
Process::initState
ArmProcess64::initState
ArmLinuxProcess64::initState
....
We have a fetch instead of a tick here compared to `AtomicSimpleCPU`, because in the timing CPU we must first get the instruction opcode from DRAM, which takes some cycles to return! We have a fetch instead of a tick here compared to `AtomicSimpleCPU`, because in the timing CPU we must first get the instruction opcode from DRAM, which takes some cycles to return!
By looking at the source, we see that fetchEvent runs `TimingSimpleCPU::fetch`. By looking at the source, we see that `fetchEvent` runs `TimingSimpleCPU::fetch`.
`0: system.mem_ctrls_0.wrapped_function_event: EventFunctionWrapped event scheduled @ 7786250`: from GDB we see that it comes from `DRAMCtrl::startup` in `mem/dram_ctrl.cc` which contains: The next event line is:
....
0: system.mem_ctrls_0.wrapped_function_event: EventFunctionWrapped event scheduled @ 7786250
....
From GDB we see that it comes from `DRAMCtrl::startup` in `mem/dram_ctrl.cc` with a short backtrace:
....
EventManager::schedule
DRAMCtrl::Rank::startup
DRAMCtrl::startup (this
....
which contains:
.... ....
void void
@@ -13322,6 +13403,25 @@ DRAMCtrl::Rank::startup(Tick ref_tick)
} }
.... ....
`startup` itself a `SimObject` method exposed to Python and called from `simulate` in `src/python/m5/simulate.py`:
....
def simulate(*args, **kwargs):
global need_startup
if need_startup:
root = objects.Root.getInstance()
for obj in root.descendants(): obj.startup()
....
where `simulate` happens after `m5.instantiate`, and both are called directly from the toplevel scripts, e.g. for se.py in `configs/common/Simulation.py`:
....
def run(options, root, testsys, cpu_class):
...
exit_event = m5.simulate()
....
By looking up some variable definitions in the source, we now we see some memory parameters clearly: By looking up some variable definitions in the source, we now we see some memory parameters clearly:
* ranks: `std::vector<DRAMCtrl::Rank*>` with 2 elements. TODO why do we have 2? What does it represent? Likely linked to <<gem5-config-ini,`config.ini`>> at `system.mem_ctrls.ranks_per_channel=2` * ranks: `std::vector<DRAMCtrl::Rank*>` with 2 elements. TODO why do we have 2? What does it represent? Likely linked to <<gem5-config-ini,`config.ini`>> at `system.mem_ctrls.ranks_per_channel=2`
@@ -13356,47 +13456,96 @@ So we realize that we are going into deep DRAM modelling, more detail that a mer
`curTick() + tREFI - tRP = 0 + 7800000 - 13750 = 7786250` which is when that `refreshEvent` was scheduled. Our simulation ends way before that point however, so we will never know what it did thank God. `curTick() + tREFI - tRP = 0 + 7800000 - 13750 = 7786250` which is when that `refreshEvent` was scheduled. Our simulation ends way before that point however, so we will never know what it did thank God.
`0: Event_74: generic event scheduled @ 0` and `0: Event_74: generic event rescheduled @ 18446744073709551615`: schedule the final exit event, same as for `AtomicSimpleCPU` The next event:
The next interesting event is:
.... ....
system.mem_ctrls.wrapped_function_event: EventFunctionWrapped event scheduled @ 0 0: Event: system.mem_ctrls_1.wrapped_function_event: EventFunctionWrapped 20 scheduled @ 7786250
.... ....
which comes from: must be coming from the `startup` of the second memory controller object.
`se.py` allocates the memory controllers via `configs/common/MemConfig.py`:
.... ....
#0 Trace::OstreamLogger::logMessage
#1 void Trace::Logger::dprintf def config_mem(options, system):
#2 Event::trace
#3 EventQueue::schedule ...
#4 EventManager::schedule
#5 DRAMCtrl::addToReadQueue opt_mem_channels = options.mem_channels
#6 DRAMCtrl::recvTimingReq
#7 DRAMCtrl::MemoryPort::recvTimingReq ...
#8 TimingRequestProtocol::sendReq
#9 MasterPort::sendTimingReq nbr_mem_ctrls = opt_mem_channels
#10 CoherentXBar::recvTimingReq
#11 CoherentXBar::CoherentXBarSlavePort::recvTimingReq(Packet*)) ...
#12 TimingRequestProtocol::sendReq
#13 MasterPort::sendTimingReq for r in system.mem_ranges:
#14 TimingSimpleCPU::sendFetch for i in range(nbr_mem_ctrls):
#15 TimingSimpleCPU::FetchTranslation::finish mem_ctrl = create_mem_ctrl(cls, r, i, nbr_mem_ctrls, intlv_bits,
#16 ArmISA::TLB::translateComplete intlv_size)
#17 ArmISA::TLB::translateTiming
#18 ArmISA::TLB::translateTiming ...
#19 TimingSimpleCPU::fetch
#20 TimingSimpleCPU::<lambda()>::operator()(void) mem_ctrls.append(mem_ctrl)
#21 std::_Function_handler<void(), TimingSimpleCPU::TimingSimpleCPU(TimingSimpleCPUParams*)::<lambda()> >
#22 std::function<void)>::operator()() const
#23 EventFunctionWrapper::process
#24 EventQueue::serviceOne
#25 doSimLoop
#26 simulate
.... ....
From the trace, we see that we are already running from the event queue. Therefore, we must have been running a previously scheduled event, and the previous event logs, the only such event is `0: system.cpu.wrapped_function_event: EventFunctionWrapped event scheduled @ 0` which scheduled a memory fetch! but TODO that loop happens only once, why there are two such objects then?
The next events are:
....
0: Event: Event_74: generic 74 scheduled @ 0
0: Event: Event_74: generic 74 rescheduled @ 18446744073709551615
....
From the timing we know what that one is: the end of time exit event, like for `AtomicSimpleCPU`.
The next event logs are:
....
0: Event: system.cpu.wrapped_function_event: EventFunctionWrapped 43 executed @ 0
0: Event: system.mem_ctrls.wrapped_function_event: EventFunctionWrapped 9 scheduled @ 0
0: Event: system.membus.reqLayer0.wrapped_function_event: EventFunctionWrapped 60 scheduled @ 1000
....
The first line shows that event ID `43` is now executing: we had previously seen event `43` get scheduled and had analyzed it to be the initial fetch.
The second line, is an execution. The event loop has started, an magic initialization schedulings are not happening anymore: now every event is being scheduled from another event:
....
Trace::OstreamLogger::logMessage
void Trace::Logger::dprintf
Event::trace
EventQueue::schedule
EventManager::schedule
DRAMCtrl::addToReadQueue
DRAMCtrl::recvTimingReq
DRAMCtrl::MemoryPort::recvTimingReq
TimingRequestProtocol::sendReq
MasterPort::sendTimingReq
CoherentXBar::recvTimingReq
CoherentXBar::CoherentXBarSlavePort::recvTimingReq(Packet*))
TimingRequestProtocol::sendReq
MasterPort::sendTimingReq
TimingSimpleCPU::sendFetch
TimingSimpleCPU::FetchTranslation::finish
ArmISA::TLB::translateComplete
ArmISA::TLB::translateTiming
ArmISA::TLB::translateTiming
TimingSimpleCPU::fetch
TimingSimpleCPU::<lambda()>::operator()(void)
std::_Function_handler<void(), TimingSimpleCPU::TimingSimpleCPU(TimingSimpleCPUParams*)::<lambda()> >
std::function<void)>::operator()() const
EventFunctionWrapper::process
EventQueue::serviceOne
doSimLoop
simulate
....
From the trace, we see that we are already running from the event queue under `TimingSimpleCPU::fetch` as expected.
This must be the CPU fetching an instruction from the memory system to execute it!
From the backtrace we see the tortuous path that the data request takes, going through: From the backtrace we see the tortuous path that the data request takes, going through:
@@ -13404,7 +13553,7 @@ From the backtrace we see the tortuous path that the data request takes, going t
* `CoherentXBar` * `CoherentXBar`
* `DRAMCtrl` * `DRAMCtrl`
The scheduling happens at frame `#5`: The scheduling happens at frame `DRAMCtrl::addToReadQueue`:
.... ....
// If we are not already scheduled to get a request out of the // If we are not already scheduled to get a request out of the
@@ -13415,35 +13564,67 @@ The scheduling happens at frame `#5`:
} }
.... ....
and from a quick source grep we see that `nextReqEvent` is a `DRAMCtrl::processNextReqEvent`. and from a quick source grep we see that `nextReqEvent` is a `DRAMCtrl::processNextReqEvent`. From this we deduce that the DRAM has a request queue of some sort.
The next schedule: The second schedule coming from the initial fetch is:
.... ....
0: system.membus.reqLayer0.wrapped_function_event: EventFunctionWrapped event scheduled @ 1000 0: Event: system.membus.reqLayer0.wrapped_function_event: EventFunctionWrapped 60 scheduled @ 1000
.... ....
and does a `BaseXBar::Layer::releaseLayer` event. and schedules a `BaseXBar::Layer::releaseLayer` event through:
This one is also coming from the request queue at `TimingSimpleCPU::fetch`. We deduce therefore that the single previous fetch event scheduled not one, but two events! ....
EventManager::schedule
BaseXBar::Layer<SlavePort, MasterPort>::occupyLayer
BaseXBar::Layer<SlavePort, MasterPort>::succeededTiming
CoherentXBar::recvTimingReq
CoherentXBar::CoherentXBarSlavePort::recvTimingReq
TimingRequestProtocol::sendReq
MasterPort::sendTimingReq
TimingSimpleCPU::sendFetch
TimingSimpleCPU::FetchTranslation
ArmISA::TLB::translateComplete
ArmISA::TLB::translateTiming
/build/ARM/arch/arm/tlb.cc
ArmISA::TLB::translateTiming
....
TODO what does this represent.
Now: Now:
.... ....
0: system.mem_ctrls_0.wrapped_function_event: EventFunctionWrapped event scheduled @ 0 0: system.mem_ctrls_0.wrapped_function_event: EventFunctionWrapped event scheduled @ 0
.... ....
comes from the previously scheduled `DRAMCtrl::processNextReqEvent` and schedules `DRAMCtrl::Rank::processPrechargeEvent`. comes from the previously scheduled `DRAMCtrl::processNextReqEvent` and schedules `DRAMCtrl::Rank::processPrechargeEvent`.
Now: Then comes the execution:
.... ....
0: system.mem_ctrls.wrapped_function_event: EventFunctionWrapped event scheduled @ 46250 0: Event: system.mem_ctrls.wrapped_function_event: EventFunctionWrapped 9 executed @ 0
.... ....
also runs from `DRAMCtrl::processNextReqEvent` and schedules a `DRAMCtrl::processRespondEvent`. followed by three more schedules:
I'm getting bored, let's skip to the line that appears to matter for the first instruction: ....
0: Event: system.mem_ctrls_0.wrapped_function_event: EventFunctionWrapped 12 scheduled @ 0
EventManager::schedule(Event&, unsigned long)+0x30)[0x561af7237634]
DRAMCtrl::activateBank(DRAMCtrl::Rank&, DRAMCtrl::Bank&, unsigned long, unsigned int)+0xa7b)[0x561af7f24ced]
DRAMCtrl::doDRAMAccess(DRAMCtrl::DRAMPacket*)+0x2a0)[0x561af7f25602]
DRAMCtrl::processNextReqEvent()+0xdce)[0x561af7f27522]
0: Event: system.mem_ctrls.wrapped_function_event: EventFunctionWrapped 10 scheduled @ 46250
EventManager::schedule(Event&, unsigned long)+0x30)[0x561af7237634]
DRAMCtrl::processNextReqEvent()+0xf8c)[0x561af7f276e0]
0: Event: system.mem_ctrls.wrapped_function_event: EventFunctionWrapped 9 scheduled @ 5000
EventManager::schedule(Event&, unsigned long)+0x30)[0x561af7237634]
DRAMCtrl::processNextReqEvent()+0x1870)[0x561af7f27fc4]
....
TODO I got bored of DRAM modelling.
.... ....
46250: system.mem_ctrls.port-RespPacketQueue.wrapped_function_event: EventFunctionWrapped event scheduled @ 74250 46250: system.mem_ctrls.port-RespPacketQueue.wrapped_function_event: EventFunctionWrapped event scheduled @ 74250
@@ -14460,6 +14641,12 @@ Programs under link:userland/cpp/[] are examples of https://en.wikipedia.org/wik
* link:userland/cpp/empty.cpp[] * link:userland/cpp/empty.cpp[]
* link:userland/cpp/hello.cpp[] * link:userland/cpp/hello.cpp[]
* classes
** constructor
*** link:userland/cpp/initializer_list_constructor.cpp[]: documents stuff like `std::vector<int> v{0, 1};` and `std::initializer_list`
*** link:userland/cpp/most_vexing_parse.cpp[]: the most vexing parse is a famous constructor vs function declaration syntax gotcha!
**** https://en.wikipedia.org/wiki/Most_vexing_parse
**** http://stackoverflow.com/questions/180172/default-constructor-with-empty-brackets
* templates * templates
** link:userland/cpp/template.cpp[]: basic example ** link:userland/cpp/template.cpp[]: basic example
** link:userland/cpp/template_class_with_static_member.cpp[]: https://stackoverflow.com/questions/3229883/static-member-initialization-in-a-class-template ** link:userland/cpp/template_class_with_static_member.cpp[]: https://stackoverflow.com/questions/3229883/static-member-initialization-in-a-class-template
@@ -14475,10 +14662,6 @@ Programs under link:userland/cpp/[] are examples of https://en.wikipedia.org/wik
** associative ** associative
*** <<algorithms>> contains a benchmark comparison of different c++ containers *** <<algorithms>> contains a benchmark comparison of different c++ containers
*** link:userland/cpp/set.cpp[]: `std::set` contains unique keys *** link:userland/cpp/set.cpp[]: `std::set` contains unique keys
* Language madness
** link:userland/cpp/most_vexing_parse.cpp[]: the most vexing parse is a famous constructor vs function declaration syntax gotcha!
*** https://en.wikipedia.org/wiki/Most_vexing_parse
*** http://stackoverflow.com/questions/180172/default-constructor-with-empty-brackets
[[cpp-multithreading]] [[cpp-multithreading]]
==== C++ multithreading ==== C++ multithreading

14
run
View File

@@ -517,17 +517,6 @@ Extra options to append at the end of the emulator command line.
]) ])
if self.env['userland_args'] is not None: if self.env['userland_args'] is not None:
cmd.extend(['--options', self.env['userland_args'], LF]) cmd.extend(['--options', self.env['userland_args'], LF])
if not self.env['static']:
for path in self.env['userland_library_redirects']:
cmd.extend([
'--redirects',
'{}={}'.format(
os.sep + path,
os.path.join(self.env['userland_library_dir'], path)
),
LF
])
cmd.extend(['--interp-dir', self.env['userland_library_dir'], LF])
else: else:
if self.env['gem5_script'] == 'fs': if self.env['gem5_script'] == 'fs':
cmd.extend([ cmd.extend([
@@ -621,9 +610,6 @@ Extra options to append at the end of the emulator command line.
), ),
LF LF
]) ])
if self.env['gem5_script'] == 'fs' or self.env['gem5_script'] == 'biglittle':
if self.env['gem5_bootloader'] is not None:
cmd.extend(['--bootloader', self.env['gem5_bootloader'], LF])
cmd.extend(['--mem-size', memory, LF]) cmd.extend(['--mem-size', memory, LF])
if self.env['gdb_wait']: if self.env['gdb_wait']:
# https://stackoverflow.com/questions/49296092/how-to-make-gem5-wait-for-gdb-to-connect-to-reliably-break-at-start-kernel-of-th # https://stackoverflow.com/questions/49296092/how-to-make-gem5-wait-for-gdb-to-connect-to-reliably-break-at-start-kernel-of-th