├── traces ├── test.txt ├── no_delay_test.txt ├── trace_gen.py ├── loop_gen.py ├── qemu_test.txt ├── seq_page.txt ├── skip_page.txt ├── force_flash_write.txt ├── 2_seq_page.txt └── 3_seq_page.txt ├── tools ├── replay_warmup │ ├── map_all.py │ ├── count_accesses.py │ ├── mtparser.py │ └── gen_trace.py ├── ptlcalls │ ├── README │ ├── ptlcall_single_flush.c │ ├── Makefile │ ├── nop_test.cpp │ ├── ptlcall_hybridsim.cpp │ ├── util.h │ └── util.cpp ├── sweep_scripts │ ├── README │ ├── plots │ │ ├── check.sh │ │ └── plots.py │ ├── cleanup.sh │ ├── ini │ │ ├── 128_chan.ini │ │ ├── 16_chan.ini │ │ ├── 1_chan.ini │ │ ├── 256_chan.ini │ │ ├── 2_chan.ini │ │ ├── 32_chan.ini │ │ ├── 4_chan.ini │ │ ├── 64_chan.ini │ │ ├── 8_chan.ini │ │ ├── hybridsim.ini │ │ ├── prefetch.h │ │ ├── noprefetch.h │ │ └── TraceBasedSim.cpp │ └── test.sh ├── experiment_driver │ ├── my_hooks.py │ ├── README │ └── gen_traces.py ├── trace_generators │ └── set_0_abuse.py ├── mmio_analysis.py ├── perfect_prefetching │ ├── compare_states.py │ ├── compare_data.py │ ├── analyze_traces.py │ └── analyze_traces_complex.py ├── GraphGen.py └── extract │ └── merge_dict.py ├── ini ├── scheduler_prefetcher.json ├── old │ ├── samsung_K9XXG08UXM.ini │ ├── samsung_K9XXG08UXM_pcm.ini │ └── samsung_K9XXG08UXM_mod.ini ├── PCM_TEST.ini ├── loops_test.yaml ├── DDR3_micron_1M_8B_x16_sg15.ini ├── DDR3_micron_2M_8B_x16_sg15.ini ├── DDR3_micron_4M_8B_x16_sg15.ini ├── DDR3_micron_8M_8B_x16_sg15.ini ├── DDR3_micron_16M_8B_x8_sg15.ini ├── DDR3_micron_8M_8B_x8_sg15.ini ├── DDR3_micron_128M_8B_x8_sg15.ini ├── DDR3_micron_32M_8B_x8_sg15.ini ├── DDR3_micron_64M_8B_x8_sg15.ini ├── system.ini ├── jim_testing.ini ├── 32mb_loops.yaml ├── hybridsim.ini ├── samsung_K9XXG08UXM_frontbuffer.ini ├── nvdimm.ini ├── samsung_K9XXG08UXM_gc_test.ini └── scheduler_prefetcher.yaml ├── old ├── SimulatorObject.cpp ├── SimulatorObject.h ├── TraceBasedSim_paul.h ├── TraceBasedSim_writeread.cpp ├── TraceBasedSim_cache.cpp ├── TraceBasedSim_force_writeback.cpp ├── trace based tests │ ├── TraceBasedSim.cpp │ └── FlashWriteBackTest.cpp ├── test.cpp └── TraceBasedSim_paul.cpp ├── .gitignore ├── LICENSE ├── Makefile ├── TraceBasedSim.h ├── IniReader.h ├── hybridsim.py ├── util.h ├── Transaction.h ├── HybridSim.h ├── CallbackHybrid.h ├── tbs.py ├── util.cpp ├── README └── IniReader.cpp /traces/test.txt: -------------------------------------------------------------------------------- 1 | 0 0 0 2 | 100 0 64 3 | 200 0 128 4 | 300 0 192 5 | -------------------------------------------------------------------------------- /traces/no_delay_test.txt: -------------------------------------------------------------------------------- 1 | 0 0 0 2 | 1 0 64 3 | 2 0 128 4 | 3 0 192 5 | 4 0 0 6 | -------------------------------------------------------------------------------- /tools/replay_warmup/map_all.py: -------------------------------------------------------------------------------- 1 | print '4096 64 2097152 2097152' 2 | 3 | for i in range(2097152): 4 | cache_addr = i * 4096 5 | tag = i / 32768 6 | print str(cache_addr) + ' 1 0 ' + str(tag) + ' 0 0' 7 | -------------------------------------------------------------------------------- /ini/scheduler_prefetcher.json: -------------------------------------------------------------------------------- 1 | { 2 | "cores": 2, 3 | "quantum_cycles": 10000, 4 | "trace_files": ["traces/big_0.txt", "traces/big_512.txt", "traces/big_0.txt", "traces/big_512.txt"], 5 | "base_addresses": [], 6 | "schedule": [[0,2], [1,2], [2,3], [3,0]] 7 | } 8 | -------------------------------------------------------------------------------- /tools/ptlcalls/README: -------------------------------------------------------------------------------- 1 | This directory contains programs that are useful for making ptlcalls from the command line 2 | in marss. Build them and then put them in a disk image either by mounting the disk image 3 | on the host or by using the qemu nic and scp. 4 | -------------------------------------------------------------------------------- /ini/old/samsung_K9XXG08UXM.ini: -------------------------------------------------------------------------------- 1 | NUM_PACKAGES=1 2 | DIES_PER_PACKAGE=2 3 | PLANES_PER_DIE=4 4 | BLOCKS_PER_PLANE=2048 5 | PAGES_PER_BLOCK=64 6 | FLASH_PAGE_SIZE=4 7 | 8 | READ_TIME=25 9 | WRITE_TIME=200 10 | ERASE_TIME=1500 11 | DATA_TIME=100 12 | COMMAND_TIME=10 13 | LOOKUP_TIME=20 14 | -------------------------------------------------------------------------------- /old/SimulatorObject.cpp: -------------------------------------------------------------------------------- 1 | //SimulatorObject.cpp 2 | // 3 | //Base class for all classes in the simulator 4 | // 5 | 6 | #include 7 | #include "SimulatorObject.h" 8 | 9 | using namespace DRAMSim; 10 | using namespace std; 11 | 12 | void SimulatorObject::step() 13 | { 14 | currentClockCycle++; 15 | } 16 | 17 | 18 | -------------------------------------------------------------------------------- /tools/ptlcalls/ptlcall_single_flush.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "ptlcalls.h" 5 | 6 | 7 | int main(int argc, char *argv[]) 8 | { 9 | if (argc != 2) 10 | { 11 | fprintf(stderr, "Error: Need exactly 1 argument.\n"); 12 | abort(); 13 | } 14 | 15 | ptlcall_single_flush(argv[1]); 16 | } 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | Results/ 2 | results/ 3 | *.o 4 | *.po 5 | *.dep 6 | *.deppo 7 | *.swp 8 | *.h~ 9 | *.cpp~ 10 | *.log 11 | *.png 12 | *.pyc 13 | *~ 14 | out 15 | nohup.out 16 | tmp 17 | \.#* 18 | *# 19 | HybridSim 20 | libhybridsim.so 21 | NVHybridSim 22 | libnvhybridsim.so 23 | dramsim.log 24 | hybridsim.log 25 | run.sh 26 | tags 27 | state/ 28 | untracked_traces/* 29 | -------------------------------------------------------------------------------- /ini/PCM_TEST.ini: -------------------------------------------------------------------------------- 1 | DEVICE_TYPE=PCM 2 | NUM_PACKAGES=1 3 | DIES_PER_PACKAGE=2 4 | PLANES_PER_DIE=4 5 | BLOCKS_PER_PLANE=2048 6 | PAGES_PER_BLOCK=64 7 | PAGE_SIZE=4096 8 | WORDS_PER_PAGE=128 9 | READ_SIZE=64 10 | WRITE_SIZE=64 11 | 12 | 13 | READ_TIME=16678 14 | WRITE_TIME=133420 15 | ERASE_TIME=1000700 16 | DATA_TIME=66711 17 | COMMAND_TIME=6671 18 | LOOKUP_TIME=20 19 | -------------------------------------------------------------------------------- /tools/sweep_scripts/README: -------------------------------------------------------------------------------- 1 | This directory contains a set of scripts that were used for performing channel sweeps 2 | with perfect prefetching using trace-based sim mode. These can be adapted for any experiment 3 | and is just here to provide an example of working scripts to run large series of experiments. 4 | The ini directory is included to show how to copy data into the hybridsim repo. 5 | -------------------------------------------------------------------------------- /old/SimulatorObject.h: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOROBJ_H 2 | #define SIMULATOROBJ_H 3 | 4 | //SimulatorObject.h 5 | // 6 | //Header file for simulator object class 7 | // 8 | 9 | #include 10 | 11 | namespace DRAMSim 12 | { 13 | class SimulatorObject 14 | { 15 | public: 16 | uint64_t currentClockCycle; 17 | 18 | void step(); 19 | virtual void update()=0; 20 | }; 21 | } 22 | 23 | #endif 24 | 25 | -------------------------------------------------------------------------------- /tools/ptlcalls/Makefile: -------------------------------------------------------------------------------- 1 | hybridsim: 2 | g++ -c ptlcall_hybridsim.cpp 3 | g++ -c util.cpp 4 | g++ -o ptlcall_hybridsim ptlcall_hybridsim.o util.o 5 | 6 | single_flush: 7 | g++ -o ptlcall_single_flush ptlcall_single_flush.c 8 | 9 | nop_test: 10 | g++ -c nop_test.cpp 11 | g++ -c util.cpp 12 | g++ -o nop_test nop_test.o util.o 13 | 14 | clean: 15 | rm -rf *.o 16 | rm ptlcall_single_flush ptlcall_hybridsim nop_test 17 | -------------------------------------------------------------------------------- /traces/trace_gen.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | NUM_STREAMS = 10 4 | STREAM_LENGTH = 100 5 | STREAM_STEP = 4096 6 | START = 512*1024*1024 7 | STREAM_SEPARATION = 1024*1024 8 | CYCLE_STEP = 100 9 | RW_FLAG = 0 10 | 11 | cycle = 0 12 | for j in range(STREAM_LENGTH): 13 | for i in range(NUM_STREAMS): 14 | cur_addr = i*STREAM_SEPARATION + j*STREAM_STEP + START 15 | print '%d\t\t%d\t\t%d'%(cycle,RW_FLAG,cur_addr) 16 | 17 | cycle += CYCLE_STEP 18 | 19 | -------------------------------------------------------------------------------- /traces/loop_gen.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | NUM_STREAMS = 8192 4 | STREAM_LENGTH = 100 5 | STREAM_STEP = 64 6 | #START = 512*1024*1024 7 | START = 0 8 | STREAM_SEPARATION = 4096 9 | CYCLE_STEP = 100 10 | RW_FLAG = 0 11 | 12 | cycle = 0 13 | for j in range(STREAM_LENGTH): 14 | for i in range(NUM_STREAMS): 15 | cur_addr = i*STREAM_SEPARATION + j*STREAM_STEP + START 16 | print '%d\t\t%d\t\t%d'%(cycle,RW_FLAG,cur_addr) 17 | 18 | cycle += CYCLE_STEP 19 | 20 | -------------------------------------------------------------------------------- /ini/loops_test.yaml: -------------------------------------------------------------------------------- 1 | { 2 | "cores": 1, 3 | "quantum_cycles": 2666667, 4 | "trace_files": [ "traces/loop.txt", "traces/loop.txt"], 5 | "base_addresses": [0, 33554432], 6 | #"schedule": [[0,1,8,9], [2,3,10,11], [4,5,12,13], [6,7,14,15]] 7 | #"schedule": [ [0], [1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12], [13], [14], [15], [16], [17], [18], [19], [20], [21], [22], [23], [24], [25], [26], [27], [28], [29], [30], [31] ] 8 | "schedule": [ [0], [1] ] 9 | } 10 | -------------------------------------------------------------------------------- /tools/ptlcalls/nop_test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "ptlcalls.h" 5 | #include "util.h" 6 | 7 | 8 | int main(int argc, char *argv[]) 9 | { 10 | if (argc < 2) 11 | { 12 | fprintf(stderr, "Error: Need at least 1 argument.\n"); 13 | abort(); 14 | } 15 | 16 | uint64_t count; 17 | string count_str(argv[1]); 18 | convert_uint64_t(count, count_str, "first argument"); 19 | 20 | for (int i=0; i 2 | #include 3 | 4 | #include "ptlcalls.h" 5 | #include "util.h" 6 | 7 | 8 | int main(int argc, char *argv[]) 9 | { 10 | if (argc < 2) 11 | { 12 | fprintf(stderr, "Error: Need at least 1 argument.\n"); 13 | abort(); 14 | } 15 | 16 | uint64_t operation = 0; 17 | uint64_t address = 0; 18 | 19 | string op_str(argv[1]); 20 | convert_uint64_t(operation, op_str, "first argument"); 21 | 22 | if (argc > 2) 23 | { 24 | string address_str(argv[2]); 25 | convert_uint64_t(address, address_str, "second argument"); 26 | } 27 | 28 | ptlcall_hybridsim(operation, address); 29 | } 30 | -------------------------------------------------------------------------------- /tools/experiment_driver/README: -------------------------------------------------------------------------------- 1 | Python Experiment Driver for HybridSim and marss.hybridsim. 2 | 3 | The experiment_driver.py infrastructure enables the creation of experiment 4 | sweeps with minimal effort. 5 | 6 | experiment_driver.py defines three classes: 7 | * Command 8 | * ExperimentDriver 9 | * ExperimentHooks 10 | 11 | Command is an infrastructure for generating chains of shell commands 12 | from the most common commands needed to run experiments. ExperimentDriver 13 | handles setting up and running each experiment. ExperimentHooks defines 14 | experiment-specific details (e.g. directory layout). 15 | 16 | To use, create a subclass of ExperimentHooks and pass it to an instance 17 | of ExperimentDriver. ExperimentDriver will then call the various hook 18 | methods to set up and run the experiments. 19 | -------------------------------------------------------------------------------- /tools/replay_warmup/count_accesses.py: -------------------------------------------------------------------------------- 1 | # This tool is used to count accesses in a trace in GreenskySim's format. 2 | # Usage: python count_accesses.py 3 | 4 | import sys 5 | import struct 6 | 7 | with open(sys.argv[1], 'r') as f: 8 | length = 1 9 | byte = f.read(1) 10 | while ord(byte) != 0: 11 | byte = f.read(1) 12 | length += 1 13 | 14 | count = 0 15 | 16 | (byte,) = struct.unpack(' 6 | 7 | import sys 8 | import struct 9 | 10 | with open(sys.argv[1], 'r') as f: 11 | length = 1 12 | byte = f.read(1) 13 | while ord(byte) != 0: 14 | byte = f.read(1) 15 | length += 1 16 | 17 | (byte,) = struct.unpack('1 so use at your own peril 4 | JEDEC_DATA_BUS_BITS=64 ; will never change for DDR parts 5 | TRANS_QUEUE_DEPTH=512 ; transaction queue ex: READ 0xbeef 6 | CMD_QUEUE_DEPTH=512 ; command queue ex: RAS 4 7 | EPOCH_LENGTH=100000 ; length of an epoch in cycles (granularity of simulation) 8 | ROW_BUFFER_POLICY=open_page ; close_page or open_page 9 | ADDRESS_MAPPING_SCHEME=scheme2 ;valid schemes 1-6; 10 | SCHEDULING_POLICY=rank_then_bank_round_robin ; bank_then_rank_round_robin or rank_then_bank_round_robin 11 | QUEUING_STRUCTURE=per_rank ;per_rank or per_rank_per_bank 12 | 13 | ;for true/false, please use all lowercase 14 | DEBUG_TRANS_Q=false 15 | DEBUG_CMD_Q=false 16 | DEBUG_ADDR_MAP=false 17 | DEBUG_BUS=false 18 | DEBUG_BANKSTATE=false 19 | DEBUG_BANKS=false 20 | DEBUG_POWER=false 21 | VIS_FILE_OUTPUT=true 22 | 23 | USE_LOW_POWER=true ; go into low power mode when idle? 24 | VERIFICATION_OUTPUT=false ; should be false for normal operation 25 | TOTAL_ROW_ACCESSES=4 ; maximum number of open page requests to send to the same row before forcing a row close (to prevent starvation) 26 | -------------------------------------------------------------------------------- /tools/replay_warmup/gen_trace.py: -------------------------------------------------------------------------------- 1 | # This tool is used in the fast forwarding process to generate HybridSim format 2 | # traces from the GreenskySim format. 3 | # Usage: python gen_trace.py 4 | 5 | import sys 6 | import struct 7 | 8 | base = sys.argv[1] 9 | num_input = int(sys.argv[2]) 10 | 11 | files = [base+str(i) for i in range(num_input)] 12 | 13 | cycle = 0 14 | 15 | for filename in files: 16 | with open(filename, 'r') as f: 17 | length = 1 18 | byte = f.read(1) 19 | while ord(byte) != 0: 20 | byte = f.read(1) 21 | length += 1 22 | 23 | (byte,) = struct.unpack(' 100000: 39 | # break 40 | -------------------------------------------------------------------------------- /old/TraceBasedSim_paul.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * DRAMSim2: A Cycle Accurate DRAM simulator 3 | * 4 | * Copyright (C) 2010 Elliott Cooper-Balis 5 | * Paul Rosenfeld 6 | * Bruce Jacob 7 | * University of Maryland 8 | * 9 | * This program is free software: you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License as published by 11 | * the Free Software Foundation, either version 3 of the License, or 12 | * (at your option) any later version. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with this program. If not, see . 21 | * 22 | *****************************************************************************/ 23 | 24 | #include "HybridSystem.h" 25 | 26 | 27 | 28 | class some_object 29 | { 30 | public: 31 | void read_complete(uint, uint64_t, uint64_t); 32 | void write_complete(uint, uint64_t, uint64_t); 33 | int add_one_and_run(); 34 | }; 35 | -------------------------------------------------------------------------------- /ini/jim_testing.ini: -------------------------------------------------------------------------------- 1 | SCHEDULE=1 2 | WRITE_ON_QUEUE_SIZE=0 3 | WRITE_QUEUE_LIMIT=10 4 | IDLE_WRITE=0 5 | 6 | BUFFERED=0 7 | 8 | CRIT_LINE_FIRST=1 9 | 10 | LOGGING=0 11 | WEAR_LEVEL_LOG=0 12 | RUNTIME_WRITE=0 13 | 14 | ENABLE_NV_SAVE=0 15 | NV_SAVE_FILE=state/NVDIMM_state.txt 16 | ENABLE_NV_RESTORE=0 17 | NV_RESTORE_FILE=state/NVDIMM_state.txt 18 | 19 | #DEVICE_TYPE=PCM 20 | DEVICE_TYPE=NAND 21 | NUM_PACKAGES=1 22 | DIES_PER_PACKAGE=2 23 | PLANES_PER_DIE=4 24 | VIRTUAL_BLOCKS_PER_PLANE=4096 25 | PAGES_PER_BLOCK=64 26 | NV_PAGE_SIZE=4 27 | #DEVICE_CYCLE=25 28 | DEVICE_CYCLE=2 29 | #CHANNEL_CYCLE=5 30 | CHANNEL_CYCLE=2 31 | #DEVICE_WIDTH=8 32 | DEVICE_WIDTH=8000 33 | CHANNEL_WIDTH=8000 34 | GARBAGE_COLLECT=1 35 | 36 | #READ_TIME=90 37 | READ_TIME=1 38 | #WRITE_TIME=47020 39 | WRITE_TIME=1 40 | #ERASE_TIME=79470 41 | ERASE_TIME=1 42 | #COMMAND_LENGTH=56 43 | COMMAND_LENGTH=1 44 | #LOOKUP_TIME=20 45 | LOOKUP_TIME=1 46 | QUEUE_ACCESS_TIME=50 47 | EPOCH_TIME=200000 48 | CYCLE_TIME=1.51 49 | 50 | FTL_QUEUE_LENGTH=30 51 | CTRL_QUEUE_LENGTH=30 52 | 53 | READ_I=15 54 | WRITE_I=35 55 | ERASE_I=35 56 | STANDBY_I=0.08 57 | IN_LEAK_I=0.01 58 | OUT_LEAK_I=0.01 59 | VCC=3.3 60 | ASYNC_READ_I=30 61 | VPP_STANDBY_I=0.0002 62 | VPP_READ_I=0.002 63 | VPP_WRITE_I=0.05 64 | VPP_ERASE_I=0.05 65 | VPP=3.3 66 | 67 | IDLE_GC_THRESHOLD=0.70 68 | FORCE_GC_THRESHOLD=1.01 69 | PBLOCKS_PER_VBLOCK=1.03125 70 | -------------------------------------------------------------------------------- /ini/old/samsung_K9XXG08UXM_mod.ini: -------------------------------------------------------------------------------- 1 | SCHEDULE=0 2 | WRITE_ON_QUEUE_SIZE=0 3 | WRITE_QUEUE_LIMIT=10 4 | IDLE_WRITE=0 5 | CRTL_SCHEDULE=0 6 | CTRL_WRITE_ON_QUEUE_SIZE=0 7 | CTRL_WRITE_QUEUE_LIMIT=2 8 | CTRL_IDLE_WRITE=1 9 | 10 | BUFFERED=0 11 | IN_BUFFER_SIZE=32768 12 | OUT_BUFFER_SIZE=32768 13 | 14 | CRIT_LINE_FIRST=0 15 | 16 | LOGGING=1 17 | LOG_DIR=nvdimm_logs/ 18 | WEAR_LEVEL_LOG=0 19 | RUNTIME_WRITE=1 20 | QUEUE_EVENT_LOG=0 21 | PLANE_STATE_LOG=0 22 | 23 | ENABLE_NV_SAVE=0 24 | NV_SAVE_FILE=state/NVDIMM_state.txt 25 | ENABLE_NV_RESTORE=0 26 | NV_RESTORE_FILE=state/NVDIMM_state.txt 27 | 28 | DEVICE_TYPE=NAND 29 | NUM_PACKAGES=1 30 | DIES_PER_PACKAGE=2 31 | PLANES_PER_DIE=4 32 | VIRTUAL_BLOCKS_PER_PLANE=4096 33 | PAGES_PER_BLOCK=64 34 | NV_PAGE_SIZE=4 35 | DEVICE_CYCLE=25 36 | CHANNEL_CYCLE=5 37 | DEVICE_WIDTH=8 38 | CHANNEL_WIDTH=8 39 | GARBAGE_COLLECT=1 40 | 41 | READ_TIME=16678 42 | WRITE_TIME=133420 43 | ERASE_TIME=1000700 44 | COMMAND_LENGTH=56 45 | LOOKUP_TIME=20 46 | QUEUE_ACCESS_TIME=50 47 | EPOCH_TIME=200000 48 | CYCLE_TIME=1.51 49 | 50 | FTL_READ_QUEUE_LENGTH=30 51 | CTRL_READ_QUEUE_LENGTH=30 52 | FTL_WRITE_QUEUE_LENGTH=30 53 | CTRL_WRITE_QUEUE_LENGTH=30 54 | 55 | READ_I=15 56 | WRITE_I=15 57 | ERASE_I=15 58 | STANDBY_I=0.01 59 | IN_LEAK_I=0.01 60 | OUT_LEAK_I=0.01 61 | VCC=3.3 62 | 63 | IDLE_GC_THRESHOLD=0.70 64 | FORCE_GC_THRESHOLD=1.01 65 | PBLOCKS_PER_VBLOCK=1.03125 66 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | /********************************************************************************* 2 | * Copyright (c) 2010-2011, 3 | * Jim Stevens, Paul Tschirhart, Ishwar Singh Bhati, Mu-Tien Chang, Peter Enns, 4 | * Elliott Cooper-Balis, Paul Rosenfeld, Bruce Jacob 5 | * University of Maryland 6 | * Contact: jims [at] cs [dot] umd [dot] edu 7 | * All rights reserved. 8 | * 9 | * Redistribution and use in source and binary forms, with or without 10 | * modification, are permitted provided that the following conditions are met: 11 | * 12 | * * Redistributions of source code must retain the above copyright notice, 13 | * this list of conditions and the following disclaimer. 14 | * 15 | * * Redistributions in binary form must reproduce the above copyright notice, 16 | * this list of conditions and the following disclaimer in the documentation 17 | * and/or other materials provided with the distribution. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | *********************************************************************************/ 30 | 31 | -------------------------------------------------------------------------------- /ini/32mb_loops.yaml: -------------------------------------------------------------------------------- 1 | { 2 | "cores": 1, 3 | "quantum_cycles": 2666667, 4 | "trace_files": [ "traces/loop.txt", "traces/loop.txt", "traces/loop.txt", "traces/loop.txt", "traces/loop.txt", "traces/loop.txt", "traces/loop.txt", "traces/loop.txt", "traces/loop.txt", "traces/loop.txt", "traces/loop.txt", "traces/loop.txt", "traces/loop.txt", "traces/loop.txt", "traces/loop.txt", "traces/loop.txt", "traces/loop.txt", "traces/loop.txt", "traces/loop.txt", "traces/loop.txt", "traces/loop.txt", "traces/loop.txt", "traces/loop.txt", "traces/loop.txt", "traces/loop.txt", "traces/loop.txt", "traces/loop.txt", "traces/loop.txt", "traces/loop.txt", "traces/loop.txt", "traces/loop.txt", "traces/loop.txt" ], 5 | #"base_addresses": [0, 536870912, 1073741824, 1610612736, 2147483648, 2684354560, 3221225472, 3758096384, 4294967296, 4831838208, 5368709120, 5905580032, 6442450944, 6979321856, 7516192768, 8053063680, 8589934592, 9126805504, 9663676416, 10200547328, 10737418240, 11274289152, 11811160064, 12348030976, 12884901888, 13421772800, 13958643712, 14495514624, 15032385536, 15569256448, 16106127360, 16642998272], 6 | "base_addresses": [0, 33554432, 67108864, 100663296, 134217728, 167772160, 201326592, 234881024, 268435456, 301989888, 335544320, 369098752, 402653184, 436207616, 469762048, 503316480, 536870912, 570425344, 603979776, 637534208, 671088640, 704643072, 738197504, 771751936, 805306368, 838860800, 872415232, 905969664, 939524096, 973078528, 1006632960, 1040187392], 7 | #"schedule": [[0,1,8,9], [2,3,10,11], [4,5,12,13], [6,7,14,15]] 8 | #"schedule": [ [0], [1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12], [13], [14], [15], [16], [17], [18], [19], [20], [21], [22], [23], [24], [25], [26], [27], [28], [29], [30], [31] ] 9 | "schedule": [ [0], [1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12], [13], [14], [15], [16], [17]] 10 | } 11 | -------------------------------------------------------------------------------- /ini/hybridsim.ini: -------------------------------------------------------------------------------- 1 | # Delay of the HybridSim controller for each transaction. 2 | # This is mainly the SRAM lookup delay for cache data. 3 | CONTROLLER_DELAY=2 4 | 5 | # Logging options 6 | ENABLE_LOGGER=1 7 | EPOCH_LENGTH=200000 8 | HISTOGRAM_BIN=100 9 | HISTOGRAM_MAX=20000 10 | 11 | 12 | 13 | # Page size In bytes 14 | PAGE_SIZE=4096 15 | 16 | # Associativity of cache 17 | SET_SIZE=64 18 | 19 | # number of bytes in a single transaction, this means with PAGE_SIZE=4096, 64 transactions are needed 20 | BURST_SIZE=64 21 | 22 | # number of bytes in a single flash transaction 23 | FLASH_BURST_SIZE=4096 24 | 25 | # Number of pages total and number of pages in the cache (multiply by the page size to compute size in bytes) 26 | 27 | # 8 GB 28 | TOTAL_PAGES=2097152 29 | #TOTAL_PAGES=1048576 30 | #TOTAL_PAGES=524288 31 | 32 | # 4 GB 33 | #CACHE_PAGES=1048576 34 | #CACHE_PAGES=524288 35 | #CACHE_PAGES=262144 36 | CACHE_PAGES=131072 37 | #CACHE_PAGES=2097152 38 | 39 | 40 | # Defined in marss memoryHierachy.cpp. 41 | # Need to confirm this and make it more flexible later. 42 | CYCLES_PER_SECOND=667000000 43 | 44 | # INI files 45 | #dram_ini=ini/DDR3_micron_64M_8B_x8_sg15.ini 46 | #dram_ini=ini/DDR3_micron_32M_8B_x8_sg15.ini 47 | #dram_ini=ini/DDR3_micron_16M_8B_x8_sg15.ini 48 | dram_ini=ini/DDR3_micron_8M_8B_x8_sg15.ini 49 | flash_ini=ini/nvdimm.ini 50 | #flash_ini=ini/jim_testing.ini 51 | sys_ini=ini/system.ini 52 | 53 | # Save/Restore switches 54 | ENABLE_RESTORE=0 55 | ENABLE_SAVE=1 56 | 57 | # Save/Restore files 58 | #HYBRIDSIM_RESTORE_FILE=state/hybridsim_restore.txt 59 | HYBRIDSIM_RESTORE_FILE=state/my_state.txt 60 | NVDIMM_RESTORE_FILE=state/nvdimm_restore.txt 61 | #HYBRIDSIM_SAVE_FILE=state/hybridsim_save.txt 62 | HYBRIDSIM_SAVE_FILE=state/my_state.txt 63 | #HYBRIDSIM_SAVE_FILE=state/final_state.txt 64 | NVDIMM_SAVE_FILE=state/nvdimm_restore.txt 65 | 66 | -------------------------------------------------------------------------------- /tools/sweep_scripts/ini/hybridsim.ini: -------------------------------------------------------------------------------- 1 | # Delay of the HybridSim controller for each transaction. 2 | # This is mainly the SRAM lookup delay for cache data. 3 | CONTROLLER_DELAY=2 4 | 5 | # Logging options 6 | ENABLE_LOGGER=1 7 | EPOCH_LENGTH=200000 8 | HISTOGRAM_BIN=100 9 | HISTOGRAM_MAX=20000 10 | 11 | 12 | 13 | # Page size In bytes 14 | PAGE_SIZE=4096 15 | 16 | # Associativity of cache 17 | SET_SIZE=64 18 | 19 | # number of bytes in a single transaction, this means with PAGE_SIZE=4096, 64 transactions are needed 20 | BURST_SIZE=64 21 | 22 | # number of bytes in a single flash transaction 23 | FLASH_BURST_SIZE=4096 24 | 25 | # Number of pages total and number of pages in the cache (multiply by the page size to compute size in bytes) 26 | 27 | # 8 GB 28 | TOTAL_PAGES=2097152 29 | #TOTAL_PAGES=1048576 30 | #TOTAL_PAGES=524288 31 | 32 | # 4 GB 33 | #CACHE_PAGES=1048576 34 | #CACHE_PAGES=524288 35 | #CACHE_PAGES=262144 36 | CACHE_PAGES=131072 37 | 38 | 39 | # Defined in marss memoryHierachy.cpp. 40 | # Need to confirm this and make it more flexible later. 41 | CYCLES_PER_SECOND=667000000 42 | 43 | # INI files 44 | #dram_ini=ini/DDR3_micron_64M_8B_x8_sg15.ini 45 | #dram_ini=ini/DDR3_micron_32M_8B_x8_sg15.ini 46 | #dram_ini=ini/DDR3_micron_16M_8B_x8_sg15.ini 47 | dram_ini=ini/DDR3_micron_8M_8B_x8_sg15.ini 48 | flash_ini=ini/samsung_K9XXG08UXM_mod.ini 49 | #flash_ini=ini/jim_testing.ini 50 | sys_ini=ini/system.ini 51 | 52 | # Save/Restore switches 53 | ENABLE_RESTORE=1 54 | ENABLE_SAVE=0 55 | 56 | # Save/Restore files 57 | #HYBRIDSIM_RESTORE_FILE=state/hybridsim_restore.txt 58 | HYBRIDSIM_RESTORE_FILE=state/my_state.txt 59 | NVDIMM_RESTORE_FILE=state/nvdimm_state.txt 60 | #HYBRIDSIM_SAVE_FILE=state/hybridsim_save.txt 61 | HYBRIDSIM_SAVE_FILE=state/my_state.txt 62 | #HYBRIDSIM_SAVE_FILE=state/final_state.txt 63 | NVDIMM_SAVE_FILE=state/nvdimm_restore.txt 64 | 65 | -------------------------------------------------------------------------------- /ini/samsung_K9XXG08UXM_frontbuffer.ini: -------------------------------------------------------------------------------- 1 | SCHEDULE=0 2 | WRITE_ON_QUEUE_SIZE=0 3 | WRITE_QUEUE_LIMIT=10 4 | IDLE_WRITE=0 5 | CRTL_SCHEDULE=0 6 | CTRL_WRITE_ON_QUEUE_SIZE=0 7 | CTRL_WRITE_QUEUE_LIMIT=2 8 | CTRL_IDLE_WRITE=1 9 | PERFECT_SCHEDULE=0 10 | ENABLE_WRITE_SCRIPT=0 11 | NV_WRITE_SCRIPT=script/Script.txt 12 | DELAY_WRITE=0 13 | DELAY_WRITE_CYCLES=0 14 | 15 | DISK_READ=1 16 | 17 | FRONT_BUFFER=1 18 | REQUEST_BUFFER_SIZE=3276800 19 | RESPONSE_BUFFER_SIZE=3276800 20 | BUFFERED=1 21 | CUT_THROUGH=0 22 | IN_BUFFER_SIZE=32768 23 | OUT_BUFFER_SIZE=32768 24 | 25 | CRIT_LINE_FIRST=0 26 | 27 | LOGGING=1 28 | LOG_DIR=nvdimm_logs/ 29 | WEAR_LEVEL_LOG=0 30 | RUNTIME_WRITE=0 31 | PER_PACKAGE=0 32 | QUEUE_EVENT_LOG=0 33 | PLANE_STATE_LOG=0 34 | WRITE_ARRIVE_LOG=0 35 | READ_ARRIVE_LOG=0 36 | 37 | ENABLE_NV_SAVE=0 38 | NV_SAVE_FILE=state/myaddresses.txt 39 | ENABLE_NV_RESTORE=0 40 | NV_RESTORE_FILE=state/myaddresses.txt 41 | 42 | DEVICE_TYPE=NAND 43 | NUM_PACKAGES=1 44 | DIES_PER_PACKAGE=2 45 | PLANES_PER_DIE=4 46 | VIRTUAL_BLOCKS_PER_PLANE=2048 47 | PAGES_PER_BLOCK=64 48 | NV_PAGE_SIZE=4 49 | DEVICE_CYCLE=25 50 | DEVICE_WIDTH=8 51 | 52 | CHANNEL_CYCLE=5 53 | CHANNEL_WIDTH=8 54 | 55 | ENABLE_COMMAND_CHANNEL=0 56 | COMMAND_CHANNEL_WIDTH=8 57 | 58 | ENABLE_REQUEST_CHANNEL=0 59 | REQUEST_CHANNEL_WIDTH=32 60 | 61 | GARBAGE_COLLECT=1 62 | PRESTATE=0 63 | PERCENT_FULL=0 64 | 65 | READ_TIME=16678 66 | WRITE_TIME=133420 67 | ERASE_TIME=1000700 68 | COMMAND_LENGTH=56 69 | LOOKUP_TIME=20 70 | BUFFER_LOOKUP_TIME=20 71 | QUEUE_ACCESS_TIME=50 72 | EPOCH_TIME=200000 73 | CYCLE_TIME=1.51 74 | SYSTEM_CYCLE=1.51 75 | 76 | FTL_READ_QUEUE_LENGTH=30 77 | CTRL_READ_QUEUE_LENGTH=30 78 | FTL_WRITE_QUEUE_LENGTH=30 79 | CTRL_WRITE_QUEUE_LENGTH=30 80 | 81 | READ_I=15 82 | WRITE_I=15 83 | ERASE_I=15 84 | STANDBY_I=0.01 85 | IN_LEAK_I=0.01 86 | OUT_LEAK_I=0.01 87 | VCC=3.3 88 | 89 | IDLE_GC_THRESHOLD=0.70 90 | FORCE_GC_THRESHOLD=1.01 91 | PBLOCKS_PER_VBLOCK=1.03125 92 | -------------------------------------------------------------------------------- /tools/mmio_analysis.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | SET_SIZE = 64 4 | PAGE_SIZE = 4096 5 | CACHE_PAGES = 131072 6 | TOTAL_PAGES = 2097152 7 | BURST_SIZE = 64 8 | 9 | HALF_GIG = 2**29 10 | TOTAL_BYTES = TOTAL_PAGES * PAGE_SIZE + HALF_GIG 11 | 12 | def PAGE_NUMBER(addr): 13 | return addr / PAGE_SIZE 14 | def PAGE_ADDRESS(addr): 15 | return ((addr / PAGE_SIZE) * PAGE_SIZE) 16 | def PAGE_OFFSET(addr): 17 | return (addr % PAGE_SIZE) 18 | def SET_INDEX(addr): 19 | return (PAGE_NUMBER(addr) % NUM_SETS) 20 | def TAG(addr): 21 | return (PAGE_NUMBER(addr) / NUM_SETS) 22 | def FLASH_ADDRESS(tag, set_num): 23 | return ((tag * NUM_SETS + set_num) * PAGE_SIZE) 24 | def ALIGN(addr): 25 | return (((addr / BURST_SIZE) * BURST_SIZE) % (TOTAL_PAGES * PAGE_SIZE)) 26 | 27 | tracefile = open(sys.argv[1], 'r') 28 | 29 | count = {} 30 | for i in range(TOTAL_BYTES / HALF_GIG): 31 | count[i] = 0 32 | 33 | max_address = 0 34 | 35 | j = 0 36 | all_fs = 0 37 | other_large = 0 38 | other_large_list = [] 39 | 40 | while(1): 41 | # Parse line 42 | line = tracefile.readline() 43 | if line == '': 44 | break 45 | [cycle, op, address] = [int(i) for i in line.strip().split()] 46 | 47 | # Check for illegal address 48 | if address == 0xFFFFFFFFFFFFFFFF: 49 | all_fs += 1 50 | address = ALIGN(address) 51 | elif address >= TOTAL_BYTES: 52 | other_large += 1 53 | other_large_list.append(address) 54 | address = ALIGN(address) 55 | 56 | # Track address range 57 | count_index = address / HALF_GIG 58 | try: 59 | count[count_index] += 1 60 | except Exception, e: 61 | print address 62 | print count_index 63 | raise e 64 | 65 | # Track Max Address 66 | if address > max_address and address != 0xFFFFFFFFFFFFFFFF: 67 | max_address = address 68 | 69 | # Print Progress 70 | j += 1 71 | if j % 100000 == 0: 72 | print j 73 | 74 | print 'counts',count 75 | print 'All F addresses:',all_fs 76 | print 'Other large',other_large, other_large_list 77 | print 'max_address',max_address 78 | 79 | tracefile.close() 80 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # HybridSim build system 2 | 3 | ################################################### 4 | 5 | CXXFLAGS=-m64 -DNO_STORAGE -Wall -DDEBUG_BUILD -std=c++0x 6 | OPTFLAGS=-m64 -O3 7 | 8 | 9 | ifdef DEBUG 10 | ifeq ($(DEBUG), 1) 11 | OPTFLAGS= -O0 -g 12 | endif 13 | endif 14 | CXXFLAGS+=$(OPTFLAGS) 15 | 16 | CUR_DIRECTORY=$(shell pwd) 17 | DRAM_LIB=$(CUR_DIRECTORY)/../DRAMSim2 18 | NV_LIB=$(CUR_DIRECTORY)/../NVDIMMSim/src 19 | #NV_LIB=$(CUR_DIRECTORY)/../FNVSim 20 | 21 | INCLUDES=-I$(DRAM_LIB) -I$(NV_LIB) 22 | LIBS=-L${DRAM_LIB} -L${NV_LIB} -ldramsim -lnvdsim -Wl,-rpath ${DRAM_LIB} -Wl,-rpath ${NV_LIB} 23 | 24 | EXE_NAME=HybridSim 25 | LIB_NAME=libhybridsim.so 26 | LIB_NAME_MACOS=libhybridsim.dylib 27 | 28 | SRC = $(wildcard *.cpp) 29 | OBJ = $(addsuffix .o, $(basename $(SRC))) 30 | POBJ = $(addsuffix .po, $(basename $(SRC))) 31 | REBUILDABLES=$(OBJ) ${POBJ} $(EXE_NAME) $(LIB_NAME) 32 | 33 | all: ${EXE_NAME} 34 | 35 | lib: ${LIB_NAME} 36 | 37 | # $@ target name, $^ target deps, $< matched pattern 38 | $(EXE_NAME): $(OBJ) 39 | $(CXX) $(CXXFLAGS) -o $@ $^ ${LIBS} 40 | @echo "Built $@ successfully" 41 | 42 | ${LIB_NAME}: ${POBJ} 43 | $(CXX) -g -shared -Wl,-soname,$@ -o $@ $^ ${LIBS} 44 | @echo "Built $@ successfully" 45 | 46 | ${LIB_NAME_MACOS}: ${POBJ} 47 | $(CXX) -g -dynamiclib -o $@ $^ ${LIBS} 48 | @echo "Built $@ successfully" 49 | 50 | #include the autogenerated dependency files for each .o file 51 | -include $(OBJ:.o=.dep) 52 | -include $(POBJ:.po=.deppo) 53 | 54 | # build dependency list via gcc -M and save to a .dep file 55 | %.dep : %.cpp 56 | @$(CXX) $(INCLUDES) -std=c++0x -M $(CXXFLAGS) $< > $@ 57 | %.deppo : %.cpp 58 | @$(CXX) $(INCLUDES) -std=c++0x -M $(CXXFLAGS) -MT"$*.po" $< > $@ 59 | 60 | # build all .cpp files to .o files 61 | %.o : %.cpp 62 | $(CXX) $(CXXFLAGS) $(INCLUDES) -o $@ -c $< 63 | 64 | %.po : %.cpp 65 | $(CXX) $(INCLUDES) -std=c++0x -O3 -g -ffast-math -fPIC -DNO_OUTPUT -DNO_STORAGE -o $@ -c $< 66 | 67 | clean: 68 | rm -rf ${REBUILDABLES} *.dep *.deppo out results *.log callgrind* 69 | -------------------------------------------------------------------------------- /ini/nvdimm.ini: -------------------------------------------------------------------------------- 1 | SCHEDULE=0 2 | WRITE_ON_QUEUE_SIZE=1 3 | WRITE_QUEUE_LIMIT=20 4 | IDLE_WRITE=0 5 | CTRL_SCHEDULE=0 6 | CTRL_WRITE_ON_QUEUE_SIZE=0 7 | CTRL_WRITE_QUEUE_LIMIT=2 8 | CTRL_IDLE_WRITE=1 9 | PERFECT_SCHEDULE=0 10 | ENABLE_WRITE_SCRIPT=0 11 | NV_WRITE_SCRIPT=write_script.txt 12 | DELAY_WRITE=0 13 | DELAY_WRITE_CYCLES=50 14 | 15 | DISK_READ=1 16 | 17 | FRONT_BUFFER=1 18 | REQUEST_BUFFER_SIZE=3276800 19 | RESPONSE_BUFFER_SIZE=3276800 20 | BUFFERED=0 21 | CUT_THROUGH=0 22 | IN_BUFFER_SIZE=330000 23 | OUT_BUFFER_SIZE=330000 24 | 25 | CRIT_LINE_FIRST=0 26 | 27 | LOGGING=1 28 | LOG_DIR=nvdimm_ps_logs/ 29 | WEAR_LEVEL_LOG=0 30 | RUNTIME_WRITE=1 31 | PER_PACKAGE=0 32 | QUEUE_EVENT_LOG=0 33 | PLANE_STATE_LOG=1 34 | WRITE_ARRIVE_LOG=1 35 | READ_ARRIVE_LOG=1 36 | 37 | ENABLE_NV_SAVE=0 38 | NV_SAVE_FILE=state/nvdimm_state.txt 39 | ENABLE_NV_RESTORE=0 40 | NV_RESTORE_FILE=state/nvdimm_state.txt 41 | 42 | DEVICE_TYPE=NAND 43 | NUM_PACKAGES=16 44 | DIES_PER_PACKAGE=1 45 | PLANES_PER_DIE=2 46 | VIRTUAL_BLOCKS_PER_PLANE=8192 47 | PAGES_PER_BLOCK=64 48 | NV_PAGE_SIZE=4096 49 | DEVICE_CYCLE=2.5 50 | DEVICE_WIDTH=8 51 | 52 | CHANNEL_CYCLE=0.25 53 | CHANNEL_WIDTH=32 54 | 55 | ENABLE_COMMAND_CHANNEL=1 56 | COMMAND_CHANNEL_WIDTH=8 57 | 58 | ENABLE_REQUEST_CHANNEL=0 59 | REQUEST_CHANNEL_WIDTH=32 60 | 61 | GARBAGE_COLLECT=1 62 | PRESTATE=0 63 | PERCENT_FULL=0 64 | 65 | READ_TIME=25000 66 | WRITE_TIME=200000 67 | ERASE_TIME=1500000 68 | COMMAND_LENGTH=56 69 | LOOKUP_TIME=0 70 | BUFFER_LOOKUP_TIME=30 71 | QUEUE_ACCESS_TIME=75 72 | EPOCH_CYCLES=200000 73 | CYCLE_TIME=1.51 74 | SYSTEM_CYCLE=1.51 75 | 76 | FTL_READ_QUEUE_LENGTH=2 77 | CTRL_READ_QUEUE_LENGTH=15 78 | FTL_WRITE_QUEUE_LENGTH=2 79 | CTRL_WRITE_QUEUE_LENGTH=15 80 | 81 | READ_I=15 82 | WRITE_I=35 83 | ERASE_I=35 84 | STANDBY_I=0.08 85 | IN_LEAK_I=0.01 86 | OUT_LEAK_I=0.01 87 | VCC=3.3 88 | ASYNC_READ_I=30 89 | VPP_STANDBY_I=0.0002 90 | VPP_READ_I=0.002 91 | VPP_WRITE_I=0.05 92 | VPP_ERASE_I=0.05 93 | VPP=3.3 94 | 95 | IDLE_GC_THRESHOLD=0.70 96 | FORCE_GC_THRESHOLD=1.01 97 | PBLOCKS_PER_VBLOCK=1.03125 98 | -------------------------------------------------------------------------------- /TraceBasedSim.h: -------------------------------------------------------------------------------- 1 | /********************************************************************************* 2 | * Copyright (c) 2010-2011, 3 | * Jim Stevens, Paul Tschirhart, Ishwar Singh Bhati, Mu-Tien Chang, Peter Enns, 4 | * Elliott Cooper-Balis, Paul Rosenfeld, Bruce Jacob 5 | * University of Maryland 6 | * Contact: jims [at] cs [dot] umd [dot] edu 7 | * All rights reserved. 8 | * 9 | * Redistribution and use in source and binary forms, with or without 10 | * modification, are permitted provided that the following conditions are met: 11 | * 12 | * * Redistributions of source code must retain the above copyright notice, 13 | * this list of conditions and the following disclaimer. 14 | * 15 | * * Redistributions in binary form must reproduce the above copyright notice, 16 | * this list of conditions and the following disclaimer in the documentation 17 | * and/or other materials provided with the distribution. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | *********************************************************************************/ 30 | 31 | 32 | #include "HybridSystem.h" 33 | 34 | 35 | 36 | class HybridSimTBS 37 | { 38 | public: 39 | void read_complete(uint, uint64_t, uint64_t); 40 | void write_complete(uint, uint64_t, uint64_t); 41 | int run_trace(string tracefile); 42 | }; 43 | -------------------------------------------------------------------------------- /ini/samsung_K9XXG08UXM_gc_test.ini: -------------------------------------------------------------------------------- 1 | SCHEDULE=0 2 | WRITE_ON_QUEUE_SIZE=1 3 | WRITE_QUEUE_LIMIT=20 4 | IDLE_WRITE=0 5 | CTRL_SCHEDULE=0 6 | CTRL_WRITE_ON_QUEUE_SIZE=0 7 | CTRL_WRITE_QUEUE_LIMIT=2 8 | CTRL_IDLE_WRITE=1 9 | PERFECT_SCHEDULE=0 10 | ENABLE_WRITE_SCRIPT=0 11 | NV_WRITE_SCRIPT=write_script.txt 12 | DELAY_WRITE=0 13 | DELAY_WRITE_CYCLES=50 14 | 15 | DISK_READ=1 16 | 17 | FRONT_BUFFER=1 18 | REQUEST_BUFFER_SIZE=3276800 19 | RESPONSE_BUFFER_SIZE=3276800 20 | BUFFERED=0 21 | CUT_THROUGH=0 22 | IN_BUFFER_SIZE=330000 23 | OUT_BUFFER_SIZE=330000 24 | 25 | CRIT_LINE_FIRST=0 26 | 27 | LOGGING=1 28 | LOG_DIR=nvdimm_ps_logs/ 29 | WEAR_LEVEL_LOG=0 30 | RUNTIME_WRITE=1 31 | PER_PACKAGE=0 32 | QUEUE_EVENT_LOG=0 33 | PLANE_STATE_LOG=1 34 | WRITE_ARRIVE_LOG=1 35 | READ_ARRIVE_LOG=1 36 | 37 | ENABLE_NV_SAVE=0 38 | NV_SAVE_FILE=state/nvdimm_state.txt 39 | ENABLE_NV_RESTORE=0 40 | NV_RESTORE_FILE=state/nvdimm_state.txt 41 | 42 | DEVICE_TYPE=NAND 43 | NUM_PACKAGES=16 44 | DIES_PER_PACKAGE=1 45 | PLANES_PER_DIE=2 46 | VIRTUAL_BLOCKS_PER_PLANE=8192 47 | PAGES_PER_BLOCK=64 48 | NV_PAGE_SIZE=4096 49 | DEVICE_CYCLE=2.5 50 | DEVICE_WIDTH=8 51 | 52 | CHANNEL_CYCLE=0.25 53 | CHANNEL_WIDTH=32 54 | 55 | ENABLE_COMMAND_CHANNEL=1 56 | COMMAND_CHANNEL_WIDTH=8 57 | 58 | ENABLE_REQUEST_CHANNEL=0 59 | REQUEST_CHANNEL_WIDTH=32 60 | 61 | GARBAGE_COLLECT=1 62 | PRESTATE=0 63 | PERCENT_FULL=0 64 | 65 | READ_TIME=16678 66 | WRITE_TIME=133420 67 | ERASE_TIME=1000700 68 | COMMAND_LENGTH=56 69 | LOOKUP_TIME=20 70 | BUFFER_LOOKUP_TIME=20 71 | QUEUE_ACCESS_TIME=50 72 | EPOCH_TIME=200000 73 | CYCLE_TIME=1.51 74 | SYSTEM_CYCLE=1.51 75 | 76 | FTL_READ_QUEUE_LENGTH=2 77 | CTRL_READ_QUEUE_LENGTH=15 78 | FTL_WRITE_QUEUE_LENGTH=2 79 | CTRL_WRITE_QUEUE_LENGTH=15 80 | 81 | READ_I=15 82 | WRITE_I=35 83 | ERASE_I=35 84 | STANDBY_I=0.08 85 | IN_LEAK_I=0.01 86 | OUT_LEAK_I=0.01 87 | VCC=3.3 88 | ASYNC_READ_I=30 89 | VPP_STANDBY_I=0.0002 90 | VPP_READ_I=0.002 91 | VPP_WRITE_I=0.05 92 | VPP_ERASE_I=0.05 93 | VPP=3.3 94 | 95 | IDLE_GC_THRESHOLD=0.70 96 | FORCE_GC_THRESHOLD=1.01 97 | PBLOCKS_PER_VBLOCK=1.03125 98 | -------------------------------------------------------------------------------- /ini/scheduler_prefetcher.yaml: -------------------------------------------------------------------------------- 1 | { 2 | "cores": 4, 3 | "quantum_cycles": 2666667, 4 | #"trace_files": ["traces/big_0.txt", "traces/big_512.txt", "traces/big_0.txt", "traces/big_512.txt"], 5 | "trace_files": ["/home/jims/experiment/traces_10G/trace_run/NPB_32G___bt_B_16/marss.hybridsim/full_trace.log", 6 | "/home/jims/experiment/traces_10G/trace_run/NPB_32G___bt_C_16/marss.hybridsim/full_trace.log", 7 | "/home/jims/experiment/traces_10G/trace_run/NPB_32G___ft_B_16/marss.hybridsim/full_trace.log", 8 | "/home/jims/experiment/traces_10G/trace_run/NPB_32G___ft_C_16/marss.hybridsim/full_trace.log", 9 | "/home/jims/experiment/traces_10G/trace_run/NPB_32G___is_C_16/marss.hybridsim/full_trace.log", 10 | "/home/jims/experiment/traces_10G/trace_run/NPB_32G___lu_C_16/marss.hybridsim/full_trace.log", 11 | "/home/jims/experiment/traces_10G/trace_run/NPB_32G___sp_C_16/marss.hybridsim/full_trace.log", 12 | "/home/jims/experiment/traces_10G/trace_run/PARSEC_32G___bodytrack_16_large/marss.hybridsim/full_trace.log", 13 | "/home/jims/experiment/traces_10G/trace_run/PARSEC_32G___bodytrack_8_large/marss.hybridsim/full_trace.log", 14 | "/home/jims/experiment/traces_10G/trace_run/PARSEC_32G___canneal_16_large/marss.hybridsim/full_trace.log", 15 | "/home/jims/experiment/traces_10G/trace_run/PARSEC_32G___canneal_8_large/marss.hybridsim/full_trace.log", 16 | "/home/jims/experiment/traces_10G/trace_run/PARSEC_32G___facesim_16_large/marss.hybridsim/full_trace.log", 17 | "/home/jims/experiment/traces_10G/trace_run/PARSEC_32G___facesim_8_large/marss.hybridsim/full_trace.log", 18 | "/home/jims/experiment/traces_10G/trace_run/PARSEC_32G___fluidanimate_16_large/marss.hybridsim/full_trace.log", 19 | "/home/jims/experiment/traces_10G/trace_run/PARSEC_32G___fluidanimate_8_large_copy/marss.hybridsim/full_trace.log", 20 | "/home/jims/experiment/traces_10G/trace_run/PARSEC_32G___fluidanimate_8_large/marss.hybridsim/full_trace.log", 21 | "traces/qemu_test.txt"], 22 | "base_addresses": [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], 23 | #"schedule": [[0,1,8,9], [2,3,10,11], [4,5,12,13], [6,7,14,15]] 24 | "schedule": [[0,1,8,16], [2,3,10,16], [4,5,12,16], [6,7,14,16], [9,11,13,15]] 25 | } 26 | -------------------------------------------------------------------------------- /tools/experiment_driver/gen_traces.py: -------------------------------------------------------------------------------- 1 | from experiment_driver import * 2 | 3 | class MyHooks(ExperimentHooks): 4 | def __init__(self): 5 | # Call the parent class constructor. 6 | super(MyHooks, self).__init__() 7 | 8 | self.mode = 'marss.hybridsim' 9 | 10 | npb_disk = 'NPB_32G' 11 | npb_snapshots = ['sp_C_16', 'is_C_16', 'ft_B_16', 'bt_C_16', 'lu_C_16', 'ft_C_16', 'bt_B_16'] 12 | npb_runs = [npb_disk+'___'+i for i in npb_snapshots] 13 | 14 | parsec_disk = 'PARSEC_32G' 15 | parsec_snapshots = ['fluidanimate_16_large', 'canneal_16_large', 'bodytrack_16_large', 'facesim_16_large', 16 | 'fluidanimate_8_large', 'canneal_8_large', 'bodytrack_8_large', 'facesim_8_large'] 17 | parsec_runs = [parsec_disk+'___'+i for i in parsec_snapshots] 18 | 19 | all_runs = npb_runs + parsec_runs 20 | 21 | self.parameters_lists = [['trace_run'], all_runs] 22 | self.dry_run = True 23 | self.sleep_time = 60 24 | self.stopinsns = '2G' 25 | 26 | def master_hybridsim_hook(self, cmd): 27 | cmd.echo('In gen_traces master_hybridsim_hook') 28 | 29 | # Set the overall size and cache size to 32 GB. 30 | cmd.sed_file('ini/hybridsim.ini', 'CACHE_PAGES=131072', 'CACHE_PAGES=8388608') 31 | cmd.sed_file('ini/hybridsim.ini', 'TOTAL_PAGES=2097152', 'TOTAL_PAGES=8388608') 32 | 33 | # Enable the trace dump from HybridSim. 34 | cmd.sed_file('config.h', '#define DEBUG_FULL_TRACE 0', '#define DEBUG_FULL_TRACE 1') 35 | 36 | def run_marss_hook(self, cmd, cur_tuple): 37 | cmd.echo('In gen_traces run_marss_hook') 38 | 39 | # Make the NVDIMM log directory (since this keeps failing at runtime). 40 | cmd.make_directory('nvdimm_ps_logs') 41 | 42 | # Unpack the parameters as the current disk and snapshot. 43 | unpacked = cur_tuple[1].split('___') 44 | self.disk_file = '/home/jims/code/disks/'+unpacked[0]+'.qcow2' 45 | self.snapshot_name = unpacked[1] 46 | cmd.echo('Setting disk_file and snapshot_name for this experiment...') 47 | 48 | # Run marss using the parent's run_marss_hook() method. 49 | super(MyHooks, self).run_marss_hook(cmd, cur_tuple) 50 | 51 | if __name__ == '__main__': 52 | eh = MyHooks() 53 | ed = ExperimentDriver(eh) 54 | ed.run() 55 | 56 | -------------------------------------------------------------------------------- /IniReader.h: -------------------------------------------------------------------------------- 1 | /********************************************************************************* 2 | * Copyright (c) 2010-2011, 3 | * Jim Stevens, Paul Tschirhart, Ishwar Singh Bhati, Mu-Tien Chang, Peter Enns, 4 | * Elliott Cooper-Balis, Paul Rosenfeld, Bruce Jacob 5 | * University of Maryland 6 | * Contact: jims [at] cs [dot] umd [dot] edu 7 | * All rights reserved. 8 | * 9 | * Redistribution and use in source and binary forms, with or without 10 | * modification, are permitted provided that the following conditions are met: 11 | * 12 | * * Redistributions of source code must retain the above copyright notice, 13 | * this list of conditions and the following disclaimer. 14 | * 15 | * * Redistributions in binary form must reproduce the above copyright notice, 16 | * this list of conditions and the following disclaimer in the documentation 17 | * and/or other materials provided with the distribution. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | *********************************************************************************/ 30 | 31 | #ifndef HYBRIDSYSTEM_INIREADER_H 32 | #define HYBRIDSYSTEM_INIREADER_H 33 | 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | 40 | #include "util.h" 41 | 42 | using namespace std; 43 | 44 | namespace HybridSim 45 | { 46 | class IniReader 47 | { 48 | public: 49 | void read(string inifile); 50 | }; 51 | } 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /tools/perfect_prefetching/compare_states.py: -------------------------------------------------------------------------------- 1 | # This script compares the prefetch_cache_state files from multiple runs of marss. 2 | # It tells how many values in each cache set are common across all runs. 3 | 4 | import sys 5 | 6 | SET_SIZE = 64 7 | PAGE_SIZE = 4096 8 | CACHE_PAGES = 131072 9 | TOTAL_PAGES = 2097152 10 | BURST_SIZE = 64 11 | 12 | NUM_SETS = CACHE_PAGES / SET_SIZE 13 | 14 | def PAGE_NUMBER(addr): 15 | return addr / PAGE_SIZE 16 | def PAGE_ADDRESS(addr): 17 | return ((addr / PAGE_SIZE) * PAGE_SIZE) 18 | def PAGE_OFFSET(addr): 19 | return (addr % PAGE_SIZE) 20 | def SET_INDEX(addr): 21 | return (PAGE_NUMBER(addr) % NUM_SETS) 22 | def TAG(addr): 23 | return (PAGE_NUMBER(addr) / NUM_SETS) 24 | def FLASH_ADDRESS(tag, set_num): 25 | return ((tag * NUM_SETS + set_num) * PAGE_SIZE) 26 | def ALIGN(addr): 27 | return (((addr / BURST_SIZE) * BURST_SIZE) % (TOTAL_PAGES * PAGE_SIZE)) 28 | 29 | # Load all states into memory 30 | state = {} 31 | for i in range(1,6): 32 | state[i] = {} 33 | for j in range(NUM_SETS): 34 | state[i][j] = [] 35 | inFile = open(str(i)+'/prefetch_cache_state.txt', 'r') 36 | 37 | # Skip first line 38 | line = inFile.readline() 39 | 40 | while True: 41 | line = inFile.readline() 42 | if line == '': 43 | break 44 | 45 | [cache_addr, valid, dirty, tag, data, ts] = [int(k) for k in line.strip().split()] 46 | 47 | set_index = SET_INDEX(cache_addr) 48 | 49 | state[i][set_index].append(tag) 50 | 51 | # Count the values in the first set that are in all other sets 52 | set_count = [] 53 | for j in range(NUM_SETS): 54 | cur_count = 0 55 | for k in range(len(state[1][j])): 56 | cur_val = state[1][j][k] 57 | 58 | # See if the value is in all other sets. 59 | in_all = True 60 | if cur_val not in state[2][j]: 61 | in_all = False 62 | if cur_val not in state[3][j]: 63 | in_all = False 64 | if cur_val not in state[4][j]: 65 | in_all = False 66 | if cur_val not in state[5][j]: 67 | in_all = False 68 | 69 | if in_all: 70 | cur_count += 1 71 | 72 | set_count.append(cur_count) 73 | 74 | #print set_count 75 | 76 | set_count_count = {} 77 | for k in set_count: 78 | if k not in set_count_count.keys(): 79 | set_count_count[k] = 1 80 | else: 81 | set_count_count[k] += 1 82 | 83 | print set_count_count 84 | -------------------------------------------------------------------------------- /traces/qemu_test.txt: -------------------------------------------------------------------------------- 1 | 0 2 4294967232 2 | 1000 2 1040448 3 | 2000 2 1034240 4 | 3000 2 1034304 5 | 4000 0 28608 6 | 5000 2 1048192 7 | 6000 2 1048256 8 | 7000 0 1035776 9 | 8000 0 1035840 10 | 9000 2 987328 11 | 10000 0 28480 12 | 11000 2 987392 13 | 12000 2 942208 14 | 13000 2 942272 15 | 14000 2 941504 16 | 15000 0 28416 17 | 16000 2 941568 18 | 17000 0 997312 19 | 18000 2 942080 20 | 19000 0 999424 21 | 20000 2 941440 22 | 21000 2 942144 23 | 22000 0 997376 24 | 23000 2 941632 25 | 24000 2 941696 26 | 25000 2 942016 27 | 26000 2 978816 28 | 27000 2 944000 29 | 28000 2 944064 30 | 29000 2 944128 31 | 30000 2 978880 32 | 31000 2 944384 33 | 32000 2 944448 34 | 33000 2 944512 35 | 34000 0 998592 36 | 35000 2 947456 37 | 36000 2 4294865728 38 | 37000 0 28352 39 | 38000 2 4294865792 40 | 39000 0 786432 41 | 40000 0 196608 42 | 41000 0 786496 43 | 42000 0 196672 44 | 43000 0 786560 45 | 44000 0 196736 46 | 45000 0 786624 47 | 46000 0 196800 48 | 47000 0 786688 49 | 48000 0 196864 50 | 49000 0 786752 51 | 50000 0 196928 52 | 51000 0 786816 53 | 52000 0 196992 54 | 53000 0 786880 55 | 54000 0 197056 56 | 55000 0 786944 57 | 56000 0 197120 58 | 57000 0 787008 59 | 58000 0 197184 60 | 59000 0 787072 61 | 60000 0 197248 62 | 61000 0 787136 63 | 62000 0 197312 64 | 63000 0 787200 65 | 64000 0 197376 66 | 65000 0 787264 67 | 66000 0 197440 68 | 67000 0 787328 69 | 68000 0 197504 70 | 69000 0 787392 71 | 70000 0 197568 72 | 71000 0 787456 73 | 72000 0 197632 74 | 73000 0 787520 75 | 74000 0 197696 76 | 75000 0 787584 77 | 76000 0 197760 78 | 77000 0 787648 79 | 78000 0 197824 80 | 79000 0 787712 81 | 80000 0 197888 82 | 81000 0 787776 83 | 82000 0 197952 84 | 83000 0 787840 85 | 84000 0 198016 86 | 85000 0 787904 87 | 86000 0 198080 88 | 87000 0 787968 89 | 88000 0 198144 90 | 89000 0 788032 91 | 90000 0 198208 92 | 91000 0 788096 93 | 92000 0 198272 94 | 93000 0 788160 95 | 94000 0 198336 96 | 95000 0 788224 97 | 96000 0 198400 98 | 97000 0 788288 99 | 98000 0 198464 100 | 99000 0 788352 101 | 100000 0 198528 102 | -------------------------------------------------------------------------------- /hybridsim.py: -------------------------------------------------------------------------------- 1 | import ctypes 2 | from ctypes import byref 3 | from ctypes import c_ulonglong 4 | 5 | lib = ctypes.cdll.LoadLibrary('./libhybridsim.so') 6 | 7 | class HybridSim(object): 8 | def __init__(self, sys_id, ini): 9 | self.hs = lib.HybridSim_C_getMemorySystemInstance(sys_id, ini) 10 | self.read_cb = None 11 | self.write_cb = None 12 | 13 | def RegisterCallbacks(self, read_cb, write_cb): 14 | self.read_cb = read_cb 15 | self.write_cb = write_cb 16 | 17 | def addTransaction(self, isWrite, addr): 18 | return lib.HybridSim_C_addTransaction(self.hs, isWrite, c_ulonglong(addr)) 19 | 20 | def WillAcceptTransaction(self): 21 | return lib.HybridSim_C_WillAcceptTransaction(self.hs) 22 | 23 | def update(self): 24 | lib.HybridSim_C_update(self.hs) 25 | 26 | self.handle_callbacks() 27 | 28 | def handle_callbacks(self): 29 | sysID = ctypes.c_uint() 30 | addr = ctypes.c_ulonglong() 31 | cycle = ctypes.c_ulonglong() 32 | isWrite = ctypes.c_bool() 33 | 34 | while lib.HybridSim_C_PollCompletion(self.hs, byref(sysID), byref(addr), byref(cycle), byref(isWrite)): 35 | if isWrite: 36 | if self.write_cb: 37 | self.write_cb(sysID, addr, cycle) 38 | else: 39 | if self.read_cb: 40 | self.read_cb(sysID, addr, cycle) 41 | 42 | def mmio(self, operation, address): 43 | lib.HybridSim_C_mmio(self.hs, operation, address) 44 | 45 | def syncAll(self): 46 | lib.HybridSim_C_syncAll(self.hs) 47 | 48 | def reportPower(self): 49 | lib.HybridSim_C_reportPower(self.hs) 50 | 51 | def printLogfile(self): 52 | lib.HybridSim_C_printLogfile(self.hs) 53 | 54 | def read_cb(sysID, addr, cycle): 55 | print 'cycle %d: read callback from sysID %d for addr = %d'%(cycle.value, sysID.value, addr.value) 56 | def write_cb(sysID, addr, cycle): 57 | print 'cycle %d: write callback from sysID %d for addr = %d'%(cycle.value, sysID.value, addr.value) 58 | 59 | def main(): 60 | hs = HybridSim(0, '') 61 | hs.RegisterCallbacks(read_cb, write_cb) 62 | 63 | 64 | hs.addTransaction(1, 0) 65 | hs.addTransaction(1, 8) 66 | hs.addTransaction(1, 16) 67 | hs.addTransaction(1, 24) 68 | 69 | for i in range(100000): 70 | hs.update() 71 | 72 | hs.WillAcceptTransaction() 73 | hs.reportPower() 74 | hs.mmio(0,0) 75 | hs.syncAll() 76 | 77 | hs.printLogfile() 78 | 79 | 80 | if __name__ == '__main__': 81 | main() 82 | 83 | -------------------------------------------------------------------------------- /util.h: -------------------------------------------------------------------------------- 1 | /********************************************************************************* 2 | * Copyright (c) 2010-2011, 3 | * Jim Stevens, Paul Tschirhart, Ishwar Singh Bhati, Mu-Tien Chang, Peter Enns, 4 | * Elliott Cooper-Balis, Paul Rosenfeld, Bruce Jacob 5 | * University of Maryland 6 | * Contact: jims [at] cs [dot] umd [dot] edu 7 | * All rights reserved. 8 | * 9 | * Redistribution and use in source and binary forms, with or without 10 | * modification, are permitted provided that the following conditions are met: 11 | * 12 | * * Redistributions of source code must retain the above copyright notice, 13 | * this list of conditions and the following disclaimer. 14 | * 15 | * * Redistributions in binary form must reproduce the above copyright notice, 16 | * this list of conditions and the following disclaimer in the documentation 17 | * and/or other materials provided with the distribution. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | *********************************************************************************/ 30 | 31 | #ifndef HYBRIDSYSTEM_UTIL_H 32 | #define HYBRIDSYSTEM_UTIL_H 33 | 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | 42 | using namespace std; 43 | 44 | // Utility Library for HybridSim 45 | 46 | void convert_uint64_t(uint64_t &var, string value, string infostring = ""); 47 | string strip(string input, string chars = " \t\f\v\n\r"); 48 | list split(string input, string chars = " \t\f\v\n\r", size_t maxsplit=string::npos); 49 | 50 | void confirm_directory_exists(string path); 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /tools/ptlcalls/util.h: -------------------------------------------------------------------------------- 1 | /********************************************************************************* 2 | * Copyright (c) 2010-2011, 3 | * Jim Stevens, Paul Tschirhart, Ishwar Singh Bhati, Mu-Tien Chang, Peter Enns, 4 | * Elliott Cooper-Balis, Paul Rosenfeld, Bruce Jacob 5 | * University of Maryland 6 | * Contact: jims [at] cs [dot] umd [dot] edu 7 | * All rights reserved. 8 | * 9 | * Redistribution and use in source and binary forms, with or without 10 | * modification, are permitted provided that the following conditions are met: 11 | * 12 | * * Redistributions of source code must retain the above copyright notice, 13 | * this list of conditions and the following disclaimer. 14 | * 15 | * * Redistributions in binary form must reproduce the above copyright notice, 16 | * this list of conditions and the following disclaimer in the documentation 17 | * and/or other materials provided with the distribution. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | *********************************************************************************/ 30 | 31 | #ifndef HYBRIDSYSTEM_UTIL_H 32 | #define HYBRIDSYSTEM_UTIL_H 33 | 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | 42 | using namespace std; 43 | 44 | // Utility Library for HybridSim 45 | 46 | void convert_uint64_t(uint64_t &var, string value, string infostring = ""); 47 | string strip(string input, string chars = " \t\f\v\n\r"); 48 | list split(string input, string chars = " \t\f\v\n\r", size_t maxsplit=string::npos); 49 | 50 | void confirm_directory_exists(string path); 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /traces/seq_page.txt: -------------------------------------------------------------------------------- 1 | 0 0 536870912 2 | 100 0 536875008 3 | 200 0 536879104 4 | 300 0 536883200 5 | 400 0 536887296 6 | 500 0 536891392 7 | 600 0 536895488 8 | 700 0 536899584 9 | 800 0 536903680 10 | 900 0 536907776 11 | 1000 0 536911872 12 | 1100 0 536915968 13 | 1200 0 536920064 14 | 1300 0 536924160 15 | 1400 0 536928256 16 | 1500 0 536932352 17 | 1600 0 536936448 18 | 1700 0 536940544 19 | 1800 0 536944640 20 | 1900 0 536948736 21 | 2000 0 536952832 22 | 2100 0 536956928 23 | 2200 0 536961024 24 | 2300 0 536965120 25 | 2400 0 536969216 26 | 2500 0 536973312 27 | 2600 0 536977408 28 | 2700 0 536981504 29 | 2800 0 536985600 30 | 2900 0 536989696 31 | 3000 0 536993792 32 | 3100 0 536997888 33 | 3200 0 537001984 34 | 3300 0 537006080 35 | 3400 0 537010176 36 | 3500 0 537014272 37 | 3600 0 537018368 38 | 3700 0 537022464 39 | 3800 0 537026560 40 | 3900 0 537030656 41 | 4000 0 537034752 42 | 4100 0 537038848 43 | 4200 0 537042944 44 | 4300 0 537047040 45 | 4400 0 537051136 46 | 4500 0 537055232 47 | 4600 0 537059328 48 | 4700 0 537063424 49 | 4800 0 537067520 50 | 4900 0 537071616 51 | 5000 0 537075712 52 | 5100 0 537079808 53 | 5200 0 537083904 54 | 5300 0 537088000 55 | 5400 0 537092096 56 | 5500 0 537096192 57 | 5600 0 537100288 58 | 5700 0 537104384 59 | 5800 0 537108480 60 | 5900 0 537112576 61 | 6000 0 537116672 62 | 6100 0 537120768 63 | 6200 0 537124864 64 | 6300 0 537128960 65 | 6400 0 537133056 66 | 6500 0 537137152 67 | 6600 0 537141248 68 | 6700 0 537145344 69 | 6800 0 537149440 70 | 6900 0 537153536 71 | 7000 0 537157632 72 | 7100 0 537161728 73 | 7200 0 537165824 74 | 7300 0 537169920 75 | 7400 0 537174016 76 | 7500 0 537178112 77 | 7600 0 537182208 78 | 7700 0 537186304 79 | 7800 0 537190400 80 | 7900 0 537194496 81 | 8000 0 537198592 82 | 8100 0 537202688 83 | 8200 0 537206784 84 | 8300 0 537210880 85 | 8400 0 537214976 86 | 8500 0 537219072 87 | 8600 0 537223168 88 | 8700 0 537227264 89 | 8800 0 537231360 90 | 8900 0 537235456 91 | 9000 0 537239552 92 | 9100 0 537243648 93 | 9200 0 537247744 94 | 9300 0 537251840 95 | 9400 0 537255936 96 | 9500 0 537260032 97 | 9600 0 537264128 98 | 9700 0 537268224 99 | 9800 0 537272320 100 | 9900 0 537276416 101 | -------------------------------------------------------------------------------- /traces/skip_page.txt: -------------------------------------------------------------------------------- 1 | 0 0 536870912 2 | 100 0 536879104 3 | 200 0 536887296 4 | 300 0 536895488 5 | 400 0 536903680 6 | 500 0 536911872 7 | 600 0 536920064 8 | 700 0 536928256 9 | 800 0 536936448 10 | 900 0 536944640 11 | 1000 0 536952832 12 | 1100 0 536961024 13 | 1200 0 536969216 14 | 1300 0 536977408 15 | 1400 0 536985600 16 | 1500 0 536993792 17 | 1600 0 537001984 18 | 1700 0 537010176 19 | 1800 0 537018368 20 | 1900 0 537026560 21 | 2000 0 537034752 22 | 2100 0 537042944 23 | 2200 0 537051136 24 | 2300 0 537059328 25 | 2400 0 537067520 26 | 2500 0 537075712 27 | 2600 0 537083904 28 | 2700 0 537092096 29 | 2800 0 537100288 30 | 2900 0 537108480 31 | 3000 0 537116672 32 | 3100 0 537124864 33 | 3200 0 537133056 34 | 3300 0 537141248 35 | 3400 0 537149440 36 | 3500 0 537157632 37 | 3600 0 537165824 38 | 3700 0 537174016 39 | 3800 0 537182208 40 | 3900 0 537190400 41 | 4000 0 537198592 42 | 4100 0 537206784 43 | 4200 0 537214976 44 | 4300 0 537223168 45 | 4400 0 537231360 46 | 4500 0 537239552 47 | 4600 0 537247744 48 | 4700 0 537255936 49 | 4800 0 537264128 50 | 4900 0 537272320 51 | 5000 0 537280512 52 | 5100 0 537288704 53 | 5200 0 537296896 54 | 5300 0 537305088 55 | 5400 0 537313280 56 | 5500 0 537321472 57 | 5600 0 537329664 58 | 5700 0 537337856 59 | 5800 0 537346048 60 | 5900 0 537354240 61 | 6000 0 537362432 62 | 6100 0 537370624 63 | 6200 0 537378816 64 | 6300 0 537387008 65 | 6400 0 537395200 66 | 6500 0 537403392 67 | 6600 0 537411584 68 | 6700 0 537419776 69 | 6800 0 537427968 70 | 6900 0 537436160 71 | 7000 0 537444352 72 | 7100 0 537452544 73 | 7200 0 537460736 74 | 7300 0 537468928 75 | 7400 0 537477120 76 | 7500 0 537485312 77 | 7600 0 537493504 78 | 7700 0 537501696 79 | 7800 0 537509888 80 | 7900 0 537518080 81 | 8000 0 537526272 82 | 8100 0 537534464 83 | 8200 0 537542656 84 | 8300 0 537550848 85 | 8400 0 537559040 86 | 8500 0 537567232 87 | 8600 0 537575424 88 | 8700 0 537583616 89 | 8800 0 537591808 90 | 8900 0 537600000 91 | 9000 0 537608192 92 | 9100 0 537616384 93 | 9200 0 537624576 94 | 9300 0 537632768 95 | 9400 0 537640960 96 | 9500 0 537649152 97 | 9600 0 537657344 98 | 9700 0 537665536 99 | 9800 0 537673728 100 | 9900 0 537681920 101 | -------------------------------------------------------------------------------- /Transaction.h: -------------------------------------------------------------------------------- 1 | /********************************************************************************* 2 | * Copyright (c) 2010-2011, 3 | * Jim Stevens, Paul Tschirhart, Ishwar Singh Bhati, Mu-Tien Chang, Peter Enns, 4 | * Elliott Cooper-Balis, Paul Rosenfeld, Bruce Jacob 5 | * University of Maryland 6 | * Contact: jims [at] cs [dot] umd [dot] edu 7 | * All rights reserved. 8 | * 9 | * Redistribution and use in source and binary forms, with or without 10 | * modification, are permitted provided that the following conditions are met: 11 | * 12 | * * Redistributions of source code must retain the above copyright notice, 13 | * this list of conditions and the following disclaimer. 14 | * 15 | * * Redistributions in binary form must reproduce the above copyright notice, 16 | * this list of conditions and the following disclaimer in the documentation 17 | * and/or other materials provided with the distribution. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | *********************************************************************************/ 30 | 31 | #ifndef HYBRIDSIM_TRANSACTION_H 32 | #define HYBRIDSIM_TRANSACTION_H 33 | 34 | namespace HybridSim 35 | { 36 | 37 | enum TransactionType 38 | { 39 | DATA_READ, 40 | DATA_WRITE, 41 | PREFETCH, 42 | FLUSH, 43 | SYNC_ALL_COUNTER, 44 | SYNC 45 | }; 46 | 47 | class Transaction 48 | { 49 | public: 50 | //fields 51 | TransactionType transactionType; 52 | uint64_t address; 53 | void *data; 54 | 55 | //functions 56 | Transaction(TransactionType transType, uint64_t addr, void *data) 57 | { 58 | this->transactionType = transType; 59 | this->address = addr; 60 | this->data = data; 61 | } 62 | 63 | Transaction() {} 64 | 65 | //void print(); 66 | }; 67 | } 68 | 69 | #endif 70 | -------------------------------------------------------------------------------- /tools/sweep_scripts/test.sh: -------------------------------------------------------------------------------- 1 | topdir=`pwd` 2 | 3 | # Make master directory 4 | rm -rf master 5 | mkdir master 6 | cd master 7 | 8 | 9 | # Checkout and make DRAMSim 10 | git clone -b tmp https://github.com/jimstevens2001/DRAMSim2.git 11 | cd DRAMSim2 12 | make libdramsim.so 13 | cd .. 14 | 15 | # Checkout and make NVDIMM. 16 | git clone https://github.com/jimstevens2001/NVDIMMSim.git 17 | cd NVDIMMSim/src 18 | make lib 19 | cd ../.. 20 | 21 | # Checkout HybridSim 22 | git clone http://github.com/jimstevens2001/HybridSim.git 23 | 24 | # Go back to top level directory 25 | cd .. 26 | 27 | 28 | for mix in mix1 mix2 mix3 mix4; 29 | do 30 | # Clear old stuff 31 | rm -rf "$mix" 32 | 33 | # If the mix directory doesn't exist, then create it. 34 | test -e "$mix" || mkdir "$mix" 35 | cd "$mix" 36 | 37 | for chan in 1 2 4 8 16 32 64 128 256; 38 | do 39 | # If the channel directory doesn't exist, then create it. 40 | test -e "$chan"|| mkdir "$chan" 41 | cd "$chan" 42 | 43 | for config in noprefetch prefetch; 44 | do 45 | # If the prefetch option directory doesn't exist, then create it. 46 | test -e "$config" || mkdir "$config" 47 | cd "$config" 48 | 49 | echo In directory for $mix/$chan/$config 50 | 51 | # Copy repos 52 | cp -r $topdir/master/* . 53 | 54 | cd HybridSim 55 | 56 | # Copy config.h and ini files for this experiment. 57 | cp $topdir/ini/"$config".h config.h 58 | cp $topdir/ini/"$chan"_chan.ini ini/samsung_K9XXG08UXM_mod.ini 59 | cp $topdir/ini/hybridsim.ini ini/hybridsim.ini 60 | cp $topdir/ini/TraceBasedSim.cpp . 61 | 62 | # Copy fast forwarding state 63 | test -e state || mkdir state 64 | scp -r naan:/home/ibhati/disk_ff_"$mix"/state . 65 | 66 | # Copy trace to run. 67 | scp naan:~/ishwar_script/traces/original/"$mix".txt traces/"$mix".txt 68 | 69 | # Copy prefetch data 70 | #if [ "$config" == 'prefetch' ]; then 71 | #scp naan:~/ishwar_script/traces/prefetch2/"$mix"/prefetch_data.txt traces/prefetch_data.txt 72 | scp naan:~/ishwar_script/traces/prefetch2/"$mix"/prefetch_cache_state.txt state/my_state.txt 73 | #fi; 74 | 75 | # Build HybridSim 76 | make 77 | 78 | # Run Experiment 79 | nohup nice -5 ./HybridSim traces/"$mix".txt > out 2> err & 80 | 81 | # Leave HybridSim directory 82 | cd .. 83 | 84 | # Leave config directory 85 | cd .. 86 | done 87 | 88 | # Leave chan directory. 89 | cd .. 90 | done 91 | 92 | # Leave mix directory. 93 | cd .. 94 | done 95 | 96 | echo All experiments are running. 97 | -------------------------------------------------------------------------------- /traces/force_flash_write.txt: -------------------------------------------------------------------------------- 1 | 10 1 0 2 | 10 1 8388608 3 | 10 1 16777216 4 | 10 1 25165824 5 | 10 1 33554432 6 | 10 1 41943040 7 | 10 1 50331648 8 | 10 1 58720256 9 | 10 1 67108864 10 | 10 1 75497472 11 | 10 1 83886080 12 | 10 1 92274688 13 | 10 1 100663296 14 | 10 1 109051904 15 | 10 1 117440512 16 | 10 1 125829120 17 | 10 1 134217728 18 | 10 1 142606336 19 | 10 1 150994944 20 | 10 1 159383552 21 | 10 1 167772160 22 | 10 1 176160768 23 | 10 1 184549376 24 | 10 1 192937984 25 | 10 1 201326592 26 | 10 1 209715200 27 | 10 1 218103808 28 | 10 1 226492416 29 | 10 1 234881024 30 | 10 1 243269632 31 | 10 1 251658240 32 | 10 1 260046848 33 | 10 1 268435456 34 | 10 1 276824064 35 | 10 1 285212672 36 | 10 1 293601280 37 | 10 1 301989888 38 | 10 1 310378496 39 | 10 1 318767104 40 | 10 1 327155712 41 | 10 1 335544320 42 | 10 1 343932928 43 | 10 1 352321536 44 | 10 1 360710144 45 | 10 1 369098752 46 | 10 1 377487360 47 | 10 1 385875968 48 | 10 1 394264576 49 | 10 1 402653184 50 | 10 1 411041792 51 | 10 1 419430400 52 | 10 1 427819008 53 | 10 1 436207616 54 | 10 1 444596224 55 | 10 1 452984832 56 | 10 1 461373440 57 | 10 1 469762048 58 | 10 1 478150656 59 | 10 1 486539264 60 | 10 1 494927872 61 | 10 1 503316480 62 | 10 1 511705088 63 | 10 1 520093696 64 | 10 1 528482304 65 | 10 1 536870912 66 | 10 1 0 67 | 10 1 8388608 68 | 10 1 16777216 69 | 10 1 25165824 70 | 10 1 33554432 71 | 10 1 41943040 72 | 10 1 50331648 73 | 10 1 58720256 74 | 10 1 67108864 75 | 10 1 75497472 76 | 10 1 83886080 77 | 10 1 92274688 78 | 10 1 100663296 79 | 10 1 109051904 80 | 10 1 117440512 81 | 10 1 125829120 82 | 10 1 134217728 83 | 10 1 142606336 84 | 10 1 150994944 85 | 10 1 159383552 86 | 10 1 167772160 87 | 10 1 176160768 88 | 10 1 184549376 89 | 10 1 192937984 90 | 10 1 201326592 91 | 10 1 209715200 92 | 10 1 218103808 93 | 10 1 226492416 94 | 10 1 234881024 95 | 10 1 243269632 96 | 10 1 251658240 97 | 10 1 260046848 98 | 10 1 268435456 99 | 10 1 276824064 100 | 10 1 285212672 101 | 10 1 293601280 102 | 10 1 301989888 103 | 10 1 310378496 104 | 10 1 318767104 105 | 10 1 327155712 106 | 10 1 335544320 107 | 10 1 343932928 108 | 10 1 352321536 109 | 10 1 360710144 110 | 10 1 369098752 111 | 10 1 377487360 112 | 10 1 385875968 113 | 10 1 394264576 114 | 10 1 402653184 115 | 10 1 411041792 116 | 10 1 419430400 117 | 10 1 427819008 118 | 10 1 436207616 119 | 10 1 444596224 120 | 10 1 452984832 121 | 10 1 461373440 122 | 10 1 469762048 123 | 10 1 478150656 124 | 10 1 486539264 125 | 10 1 494927872 126 | 10 1 503316480 127 | 10 1 511705088 128 | 10 1 520093696 129 | 10 1 528482304 130 | 10 1 536870912 131 | -------------------------------------------------------------------------------- /tools/sweep_scripts/plots/plots.py: -------------------------------------------------------------------------------- 1 | import math 2 | 3 | import numpy as np 4 | import matplotlib as mpl 5 | mpl.use('Agg') 6 | import matplotlib.mlab as mlab 7 | import matplotlib.pyplot as plt 8 | 9 | 10 | mix = ['mix'+str(i) for i in [1,2,3,4]] 11 | chan = [1,2,4,8,16,32,64,128,256] 12 | config = ['prefetch', 'noprefetch'] 13 | 14 | metrics = ['cycles', 'miss rate', 'throughput', 'average queue length', 'average latency', 'average queue latency', 'average miss latency', 15 | 'average hit latency', 'flash idle percentage', 'dram idle percentage'] 16 | 17 | def parse_hybridsim_log(logfile): 18 | inFile = open(logfile, 'r') 19 | lines = inFile.readlines() 20 | inFile.close() 21 | [i.strip() for i in lines] 22 | 23 | result = {} 24 | 25 | result['cycles'] = int(lines[1].split(':')[1]) 26 | result['miss rate'] = float(lines[6].split(':')[1]) 27 | result['throughput'] = float(lines[11].split(':')[1].split()[0]) 28 | result['average queue length'] = float(lines[16].split(':')[1]) 29 | result['average latency'] = float(lines[7].split(':')[1].split('cycles')[0]) 30 | result['average queue latency'] = float(lines[8].split(':')[1].split('cycles')[0]) 31 | result['average miss latency'] = float(lines[9].split(':')[1].split('cycles')[0]) 32 | result['average hit latency'] = float(lines[10].split(':')[1].split('cycles')[0]) 33 | result['flash idle percentage'] = float(lines[20].split(':')[1]) 34 | result['dram idle percentage'] = float(lines[22].split(':')[1]) 35 | 36 | return result 37 | 38 | def parse_all_results(): 39 | results = {} 40 | for i in mix: 41 | results[i] = {} 42 | for j in chan: 43 | results[i][j] = {} 44 | for k in config: 45 | logfile = '../'+i+'/'+str(j)+'/'+k+'/HybridSim/hybridsim.log' 46 | 47 | results[i][j][k] = parse_hybridsim_log(logfile) 48 | return results 49 | 50 | def plot(param, data): 51 | plt.clf() 52 | 53 | print param 54 | 55 | cnt = 1 56 | for m in mix: 57 | # Collect the data I care about 58 | x = [math.log(i,2) for i in chan] 59 | y1 = [data[m][i]['noprefetch'][param] for i in chan] 60 | y2 = [data[m][i]['prefetch'][param] for i in chan] 61 | 62 | all_y = y1+y2 63 | pad_y = int((max(all_y)-min(all_y))*0.1) 64 | 65 | 66 | plt.subplot(220+cnt) 67 | l = plt.plot(x, y1, 'ko--', x, y2, 'bo--') 68 | plt.xlabel('log2(Channels)') 69 | plt.ylabel(param) 70 | plt.title(m) 71 | if param in [metrics[1], metrics[8], metrics[9]]: 72 | plt.axis([-1, 9, min(all_y), max(all_y)]) 73 | else: 74 | plt.axis([-1, 9, min(all_y)-10, max(all_y)+10]) 75 | 76 | plt.grid(True) 77 | plt.subplots_adjust(hspace=0.5, wspace=0.5) 78 | 79 | cnt += 1 80 | 81 | 82 | plt.savefig(param+'.png') 83 | 84 | 85 | data = parse_all_results() 86 | #print data['mix2'] 87 | #print mix 88 | 89 | for i in metrics: 90 | plot(i, data) 91 | -------------------------------------------------------------------------------- /HybridSim.h: -------------------------------------------------------------------------------- 1 | /********************************************************************************* 2 | * Copyright (c) 2010-2011, 3 | * Jim Stevens, Paul Tschirhart, Ishwar Singh Bhati, Mu-Tien Chang, Peter Enns, 4 | * Elliott Cooper-Balis, Paul Rosenfeld, Bruce Jacob 5 | * University of Maryland 6 | * Contact: jims [at] cs [dot] umd [dot] edu 7 | * All rights reserved. 8 | * 9 | * Redistribution and use in source and binary forms, with or without 10 | * modification, are permitted provided that the following conditions are met: 11 | * 12 | * * Redistributions of source code must retain the above copyright notice, 13 | * this list of conditions and the following disclaimer. 14 | * 15 | * * Redistributions in binary form must reproduce the above copyright notice, 16 | * this list of conditions and the following disclaimer in the documentation 17 | * and/or other materials provided with the distribution. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | *********************************************************************************/ 30 | 31 | 32 | #ifndef HYBRIDSIM_H 33 | #define HYBRIDSIM_H 34 | /* 35 | * This is a public header for DRAMSim including this along with libdramsim.so should 36 | * provide all necessary functionality to talk to an external simulator 37 | */ 38 | 39 | #include 40 | #include 41 | //#include 42 | //#include 43 | #include "CallbackHybrid.h" 44 | 45 | using std::string; 46 | typedef unsigned int uint; 47 | 48 | namespace HybridSim 49 | { 50 | class HybridSystem 51 | { 52 | public: 53 | HybridSystem(uint id, string ini); 54 | bool addTransaction(bool isWrite, uint64_t addr); 55 | bool WillAcceptTransaction(); 56 | void update(); 57 | void RegisterCallbacks( 58 | TransactionCompleteCB *readDone, 59 | TransactionCompleteCB *writeDone); 60 | void mmio(uint64_t operation, uint64_t address); 61 | void syncAll(); 62 | void reportPower(); 63 | void printLogfile(); 64 | }; 65 | HybridSystem *getMemorySystemInstance(uint id, string ini); 66 | 67 | } 68 | 69 | 70 | #endif 71 | -------------------------------------------------------------------------------- /CallbackHybrid.h: -------------------------------------------------------------------------------- 1 | /********************************************************************************* 2 | * Copyright (c) 2010-2011, 3 | * Jim Stevens, Paul Tschirhart, Ishwar Singh Bhati, Mu-Tien Chang, Peter Enns, 4 | * Elliott Cooper-Balis, Paul Rosenfeld, Bruce Jacob 5 | * University of Maryland 6 | * Contact: jims [at] cs [dot] umd [dot] edu 7 | * All rights reserved. 8 | * 9 | * Redistribution and use in source and binary forms, with or without 10 | * modification, are permitted provided that the following conditions are met: 11 | * 12 | * * Redistributions of source code must retain the above copyright notice, 13 | * this list of conditions and the following disclaimer. 14 | * 15 | * * Redistributions in binary form must reproduce the above copyright notice, 16 | * this list of conditions and the following disclaimer in the documentation 17 | * and/or other materials provided with the distribution. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | *********************************************************************************/ 30 | 31 | 32 | #ifndef HYBRIDSIM_CALLBACK_H 33 | #define HYBRIDSIM_CALLBACK_H 34 | 35 | #include 36 | 37 | using std::vector; 38 | 39 | namespace HybridSim 40 | { 41 | 42 | template 44 | class CallbackBase 45 | { 46 | public: 47 | virtual ~CallbackBase() = 0; 48 | virtual ReturnT operator()(Param1T, Param2T, Param3T) = 0; 49 | }; 50 | 51 | template 52 | HybridSim::CallbackBase::~CallbackBase() {} 53 | 54 | template 56 | class Callback: public CallbackBase 57 | { 58 | private: 59 | typedef ReturnT (ConsumerT::*PtrMember)(Param1T,Param2T,Param3T); 60 | 61 | public: 62 | Callback( ConsumerT* const object, PtrMember member) : 63 | object(object), member(member) 64 | { 65 | } 66 | 67 | Callback( const Callback& e ) : 68 | object(e.object), member(e.member) 69 | { 70 | } 71 | 72 | ReturnT operator()(Param1T param1, Param2T param2, Param3T param3) 73 | { 74 | return (const_cast(object)->*member) 75 | (param1,param2,param3); 76 | } 77 | 78 | private: 79 | 80 | ConsumerT* const object; 81 | const PtrMember member; 82 | }; 83 | 84 | typedef CallbackBase TransactionCompleteCB; 85 | typedef CallbackBase >, uint64_t> FlashPowerCB; 86 | } // namespace HybridSim 87 | 88 | #endif 89 | 90 | -------------------------------------------------------------------------------- /tbs.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | import hybridsim 4 | 5 | 6 | 7 | class HybridSimTBS(object): 8 | def __init__(self): 9 | self.MAX_PENDING=36 10 | self.MIN_PENDING=36 11 | self.complete = 0 12 | self.pending = 0 13 | self.throttle_count = 0 14 | self.throttle_cycles = 0 15 | self.final_cycles = 0 16 | 17 | self.trace_cycles = 0 18 | 19 | self.last_clock = 0 20 | self.CLOCK_DELAY = 1000000 21 | 22 | def transaction_complete(self, isWrite, sysID, addr, cycle): 23 | sysID = sysID.value 24 | addr = addr.value 25 | cycle = cycle.value 26 | 27 | self.complete += 1 28 | self.pending -= 1 29 | 30 | if (self.complete % 10000 == 0) or (cycle - self.last_clock > self.CLOCK_DELAY): 31 | print 'Complete=',self.complete,'\t\tpending=',self.pending,'\t\tcycle_count=',cycle,'\t\tthrottle_count=',self.throttle_count 32 | self.last_clock = cycle 33 | 34 | def run_trace(self, tracefile): 35 | mem = hybridsim.HybridSim(1, '') 36 | 37 | def read_cb(sysID, addr, cycle): 38 | self.transaction_complete(False, sysID, addr, cycle) 39 | def write_cb(sysID, addr, cycle): 40 | self.transaction_complete(True, sysID, addr, cycle) 41 | 42 | mem.RegisterCallbacks(read_cb, write_cb); 43 | 44 | inFile = open(tracefile, 'r') 45 | 46 | line = 'dummy value' 47 | 48 | while line: 49 | line = inFile.readline() 50 | tmp_line = line.strip().split('#')[0] 51 | if tmp_line == '': 52 | continue 53 | 54 | split_line = tmp_line.split() 55 | if len(split_line) != 3: 56 | print >> sys.stderr, 'ERROR: Parsing trace failed on line:' 57 | print >> sys.stderr, line 58 | print >> sys.stderr, 'There should be exactly three numbers per line' 59 | print >> sys.stderr, 'There are', len(split_line) 60 | sys.exit(1) 61 | 62 | line_vals = [int(i) for i in split_line] 63 | 64 | trans_cycle = int(split_line[0]) 65 | write = bool(int(split_line[1]) % 2) 66 | addr = int(split_line[2]) 67 | 68 | while (self.trace_cycles < trans_cycle): 69 | mem.update() 70 | self.trace_cycles += 1 71 | 72 | mem.addTransaction(write, addr) 73 | self.pending += 1 74 | 75 | if self.pending >= self.MAX_PENDING: 76 | self.throttle_count += 1 77 | while self.pending > self.MIN_PENDING: 78 | mem.update() 79 | self.throttle_cycles += 1 80 | 81 | 82 | inFile.close() 83 | 84 | while self.pending > 0: 85 | mem.update() 86 | self.final_cycles += 1 87 | 88 | # This is a hack for the moment to ensure that a final write completes. 89 | # In the future, we need two callbacks to fix this. 90 | # This is not counted towards the cycle counts for the run though. 91 | for i in range(1000000): 92 | mem.update() 93 | 94 | # TODO: finish this up 95 | 96 | print 'trace_cycles =',self.trace_cycles 97 | print 'throttle_count =',self.throttle_count 98 | print 'throttle_cycles =',self.throttle_cycles 99 | print 'final_cycles =',self.final_cycles 100 | print 'total_cycles = trace_cycles + throttle_cycles + final_cycles =', (self.trace_cycles + self.throttle_cycles + self.final_cycles) 101 | 102 | mem.printLogfile() 103 | 104 | def main(): 105 | tracefile = 'traces/test.txt' 106 | if len(sys.argv) > 1: 107 | tracefile = sys.argv[1] 108 | print 'Using trace file',tracefile 109 | else: 110 | print 'Using default trace file (traces/test.txt)' 111 | 112 | hs_tbs = HybridSimTBS() 113 | hs_tbs.run_trace(tracefile) 114 | 115 | 116 | if __name__ == '__main__': 117 | main() 118 | 119 | 120 | 121 | -------------------------------------------------------------------------------- /old/TraceBasedSim_writeread.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * DRAMSim2: A Cycle Accurate DRAM simulator 3 | * 4 | * Copyright (C) 2010 Elliott Cooper-Balis 5 | * Paul Rosenfeld 6 | * Bruce Jacob 7 | * University of Maryland 8 | * 9 | * This program is free software: you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License as published by 11 | * the Free Software Foundation, either version 3 of the License, or 12 | * (at your option) any later version. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with this program. If not, see . 21 | * 22 | *****************************************************************************/ 23 | 24 | 25 | 26 | #include "TraceBasedSim.h" 27 | 28 | using namespace HybridSim; 29 | using namespace std; 30 | 31 | int complete = 0; 32 | 33 | int main() 34 | { 35 | printf("dramsim_test main()\n"); 36 | some_object obj; 37 | obj.add_one_and_run(); 38 | } 39 | 40 | 41 | void some_object::read_complete(uint id, uint64_t address, uint64_t clock_cycle) 42 | { 43 | printf("[Callback] read complete: %d 0x%lx cycle=%lu\n", id, address, clock_cycle); 44 | complete++; 45 | } 46 | 47 | void some_object::write_complete(uint id, uint64_t address, uint64_t clock_cycle) 48 | { 49 | printf("[Callback] write complete: %d 0x%lx cycle=%lu\n", id, address, clock_cycle); 50 | complete++; 51 | } 52 | 53 | /* FIXME: this may be broken, currently */ 54 | void power_callback(double a, double b, double c, double d) 55 | { 56 | printf("power callback: %0.3f, %0.3f, %0.3f, %0.3f\n",a,b,c,d); 57 | } 58 | 59 | int some_object::add_one_and_run() 60 | { 61 | /* pick a DRAM part to simulate */ 62 | HybridSystem *mem = new HybridSystem(1); 63 | 64 | /* create and register our callback functions */ 65 | Callback_t *read_cb = new Callback(this, &some_object::read_complete); 66 | Callback_t *write_cb = new Callback(this, &some_object::write_complete); 67 | mem->RegisterCallbacks(read_cb, write_cb, power_callback); 68 | 69 | const int NUM_ACCESSES = 1000; 70 | 71 | for (int i=0; i= NUM_ACCESSES/2) 75 | type = DATA_READ; 76 | else 77 | type = DATA_WRITE; 78 | 79 | // Uncomment one of the following to either test different sets or the same set. 80 | uint64_t addr = (i%(NUM_ACCESSES/2)) * PAGE_SIZE; 81 | //uint64_t addr = (i%(NUM_ACCESSES/2)) * PAGE_SIZE * NUM_SETS; 82 | 83 | Transaction t = Transaction(type, addr, NULL); 84 | mem->addTransaction(t); 85 | 86 | #if DEBUG_CACHE 87 | cout << "\n\tAdded transaction " << i << " of type=" << type << " addr=" << addr << " set=" << SET_INDEX(addr) 88 | << " tag=" << TAG(addr) << endl; 89 | #endif 90 | 91 | for (int j=0; j<10000; j++) 92 | { 93 | mem->update(); 94 | } 95 | } 96 | 97 | 98 | for (int i=0; i<1000000; i++) 99 | { 100 | mem->update(); 101 | } 102 | 103 | // /* get a nice summary of this epoch */ 104 | // mem->printStats(); 105 | 106 | cout << "\n\n" << mem->currentClockCycle << ": completed " << complete << " transactions. dram_pending=" << mem->dram_pending.size() 107 | << " flash_pending=" << mem->flash_pending.size() << "\n\n"; 108 | 109 | return 0; 110 | } 111 | 112 | -------------------------------------------------------------------------------- /tools/perfect_prefetching/compare_data.py: -------------------------------------------------------------------------------- 1 | # This script is used to compare prefetch data from multiple runs of marss. 2 | # It is currently configured to compare 5 runs that are in subfolders 1,2,3,4,5. 3 | # It prints out an analysis of variance for when victims are evicted from the cache between runs. 4 | 5 | import sys 6 | import math 7 | 8 | NUM_SETS = 2048 9 | 10 | data = {} 11 | set_fails = {} 12 | max_diff = 0 13 | total_diff = 0 14 | victim_cnt = 0 15 | diff_list = [] 16 | 17 | # Load all data into memory 18 | for i in range(1,6): 19 | print 'Processing file',i 20 | data[i] = {} 21 | inFile = open(str(i)+'/prefetch_data.txt', 'r') 22 | 23 | # Double check that the number of sets for this file matches. 24 | num_sets = int(inFile.readline().strip().split()[1]) 25 | if num_sets != NUM_SETS: 26 | print 'ERROR! Number of sets does not match.' 27 | sys.exit(1) 28 | 29 | 30 | for j in range(NUM_SETS): 31 | # Consume two lines. 32 | tmp = inFile.readline() 33 | tmp = inFile.readline() 34 | 35 | data[i][j] = {} # This set maps from the address being EVICTED and the access number eviction is triggered on. 36 | set_fails[j] = [] 37 | 38 | # Parse the set declaration line. 39 | [tmp, set_num, set_cnt] = inFile.readline().strip().split() 40 | set_num = int(set_num) 41 | if set_num != j: 42 | print 'ERROR! Sets do not appear sequentially. Expected',j,'and saw',set_num 43 | sys.exit(1) 44 | set_cnt = int(set_cnt) 45 | 46 | # Parse each line. 47 | for k in range(set_cnt): 48 | [access_number, victim_page, new_page] = [int(m) for m in inFile.readline().strip().split()] 49 | if victim_page not in data[i][j]: 50 | data[i][j][victim_page] = access_number 51 | else: 52 | print 'WARNING! The victim',victim_page,'appears more than once in set',set_num 53 | sys.exit(1) 54 | 55 | if i == 5: 56 | # Analysis code 57 | 58 | fail = False 59 | for m in range(1,5): 60 | # This is a "set fail" if it is not in all five runs. 61 | if victim_page not in data[m][j]: 62 | #print 'WARNING! The victim',victim_page,'in set',set_num,'does not appear in file',m 63 | #sys.exit(1) 64 | set_fails[j].append(victim_page) 65 | fail = True 66 | break 67 | 68 | if not fail: 69 | max_access = 0 70 | min_access = 1000000000000 71 | 72 | for m in range(1,6): 73 | cur_val = data[m][j][victim_page] 74 | if cur_val > max_access: 75 | max_access = cur_val 76 | if cur_val < min_access: 77 | min_access = cur_val 78 | 79 | cur_diff = max_access - min_access 80 | if cur_diff > max_diff: 81 | max_diff = cur_diff 82 | 83 | total_diff += cur_diff 84 | victim_cnt += 1 85 | diff_list.append(cur_diff) 86 | 87 | print 'set_fails',sum([len(set_fails[j]) for j in range(NUM_SETS)]) 88 | print 'max_diff',max_diff 89 | print 'avg_diff',total_diff/float(victim_cnt) 90 | diff_list.sort() 91 | print 'median diff',diff_list[len(diff_list)/2] 92 | print 'victim_cnt',victim_cnt 93 | 94 | outFile = open('diff_list.txt', 'w') 95 | for i in diff_list: 96 | outFile.write(str(i)+'\n') 97 | outFile.close() 98 | 99 | above_10 = 0 100 | above_50 = 0 101 | above_100 = 0 102 | above_200 = 0 103 | above_300 = 0 104 | above_400 = 0 105 | for i in diff_list: 106 | if i > 10: 107 | above_10 += 1 108 | if i > 50: 109 | above_50 += 1 110 | if i > 100: 111 | above_100 += 1 112 | if i > 200: 113 | above_200 += 1 114 | if i > 300: 115 | above_300 += 1 116 | if i > 400: 117 | above_400 += 1 118 | print 'above_10',above_10 119 | print 'above_50',above_50 120 | print 'above_100',above_100 121 | print 'above_200',above_200 122 | print 'above_300',above_300 123 | print 'above_400',above_400 124 | -------------------------------------------------------------------------------- /old/TraceBasedSim_cache.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * DRAMSim2: A Cycle Accurate DRAM simulator 3 | * 4 | * Copyright (C) 2010 Elliott Cooper-Balis 5 | * Paul Rosenfeld 6 | * Bruce Jacob 7 | * University of Maryland 8 | * 9 | * This program is free software: you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License as published by 11 | * the Free Software Foundation, either version 3 of the License, or 12 | * (at your option) any later version. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with this program. If not, see . 21 | * 22 | *****************************************************************************/ 23 | 24 | 25 | 26 | #include "TraceBasedSim.h" 27 | 28 | using namespace HybridSim; 29 | using namespace std; 30 | 31 | int complete = 0; 32 | 33 | int main() 34 | { 35 | printf("dramsim_test main()\n"); 36 | some_object obj; 37 | obj.add_one_and_run(); 38 | } 39 | 40 | 41 | void some_object::read_complete(uint id, uint64_t address, uint64_t clock_cycle) 42 | { 43 | printf("[Callback] read complete: %d 0x%lx cycle=%lu\n", id, address, clock_cycle); 44 | complete++; 45 | } 46 | 47 | void some_object::write_complete(uint id, uint64_t address, uint64_t clock_cycle) 48 | { 49 | printf("[Callback] write complete: %d 0x%lx cycle=%lu\n", id, address, clock_cycle); 50 | complete++; 51 | } 52 | 53 | /* FIXME: this may be broken, currently */ 54 | void power_callback(double a, double b, double c, double d) 55 | { 56 | printf("power callback: %0.3f, %0.3f, %0.3f, %0.3f\n",a,b,c,d); 57 | } 58 | 59 | int some_object::add_one_and_run() 60 | { 61 | /* pick a DRAM part to simulate */ 62 | HybridSystem *mem = new HybridSystem(1); 63 | 64 | /* create and register our callback functions */ 65 | Callback_t *read_cb = new Callback(this, &some_object::read_complete); 66 | Callback_t *write_cb = new Callback(this, &some_object::write_complete); 67 | mem->RegisterCallbacks(read_cb, write_cb, power_callback); 68 | 69 | const int LEN = 1000; 70 | //uint64_t addr[] = {0x50000, 0x90012}; 71 | //int rd[] = {1, 0}; 72 | 73 | // for (int i=0; iaddTransaction(t); 84 | // 85 | // for (int j=0; j<1; j++) 86 | // { 87 | // mem->update(); 88 | // } 89 | // } 90 | 91 | /* create a transaction and add it */ 92 | //Transaction tr = Transaction(DATA_READ, 0x50000, NULL); 93 | Transaction tr = Transaction(DATA_WRITE, 0x50000, NULL); 94 | mem->addTransaction(tr); 95 | 96 | /* do a bunch of updates (i.e. clocks) -- at some point the callback will fire */ 97 | for (int i=0; i<100; i++) 98 | { 99 | mem->update(); 100 | } 101 | 102 | /* add another some time in the future */ 103 | //Transaction tw = Transaction(DATA_WRITE, 0x90012, NULL); 104 | Transaction tw = Transaction(DATA_READ, 0x50000, NULL); 105 | mem->addTransaction(tw); 106 | 107 | for (int i=0; i<2000; i++) 108 | { 109 | mem->update(); 110 | } 111 | 112 | /* get a nice summary of this epoch */ 113 | mem->printStats(); 114 | 115 | cout << "\ncompleted " << complete << " transactions.\n\n"; 116 | 117 | return 0; 118 | } 119 | 120 | -------------------------------------------------------------------------------- /util.cpp: -------------------------------------------------------------------------------- 1 | /********************************************************************************* 2 | * Copyright (c) 2010-2011, 3 | * Jim Stevens, Paul Tschirhart, Ishwar Singh Bhati, Mu-Tien Chang, Peter Enns, 4 | * Elliott Cooper-Balis, Paul Rosenfeld, Bruce Jacob 5 | * University of Maryland 6 | * Contact: jims [at] cs [dot] umd [dot] edu 7 | * All rights reserved. 8 | * 9 | * Redistribution and use in source and binary forms, with or without 10 | * modification, are permitted provided that the following conditions are met: 11 | * 12 | * * Redistributions of source code must retain the above copyright notice, 13 | * this list of conditions and the following disclaimer. 14 | * 15 | * * Redistributions in binary form must reproduce the above copyright notice, 16 | * this list of conditions and the following disclaimer in the documentation 17 | * and/or other materials provided with the distribution. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | *********************************************************************************/ 30 | 31 | #include "util.h" 32 | 33 | void convert_uint64_t(uint64_t &var, string value, string infostring) 34 | { 35 | // Check that each character in value is a digit. 36 | for(size_t i = 0; i < value.size(); i++) 37 | { 38 | if(!isdigit(value[i])) 39 | { 40 | cerr << "ERROR: Non-digit character found: " << infostring << " : " << value << "\n"; 41 | abort(); 42 | } 43 | } 44 | 45 | // Convert it 46 | stringstream ss; 47 | ss << value; 48 | ss >> var; 49 | } 50 | 51 | string strip(string input, string chars) 52 | { 53 | size_t pos; 54 | 55 | // Strip front. 56 | pos = input.find_first_not_of(chars); 57 | input.erase(0, pos); 58 | 59 | // Strip back. 60 | pos = input.find_last_not_of(chars); 61 | input.erase(pos+1); 62 | 63 | return input; 64 | } 65 | 66 | 67 | list split(string input, string chars, size_t maxsplit) 68 | { 69 | list ret; 70 | 71 | string cur = input; 72 | 73 | size_t pos = 0; 74 | 75 | if (maxsplit == 0) 76 | maxsplit = 1; 77 | 78 | while (!cur.empty()) 79 | { 80 | if (ret.size() == (maxsplit-1)) 81 | { 82 | ret.push_back(cur); 83 | return ret; 84 | } 85 | 86 | pos = cur.find_first_of(chars); 87 | string tmp = cur.substr(0, pos); 88 | ret.push_back(tmp); 89 | 90 | 91 | if (pos == string::npos) 92 | cur.erase(); 93 | else 94 | { 95 | // Skip ahead to the next non-split char 96 | size_t new_pos = cur.find_first_not_of(chars, pos); 97 | //cur.erase(0, pos+1); 98 | cur.erase(0, new_pos); 99 | } 100 | } 101 | 102 | // If not at npos, then there is still an extra empty string at the end. 103 | if (pos != string::npos) 104 | { 105 | ret.push_back(""); 106 | } 107 | 108 | return ret; 109 | } 110 | 111 | void confirm_directory_exists(string path) 112 | { 113 | string command_str = "test -e "+path+" || mkdir "+path; 114 | const char * command = command_str.c_str(); 115 | int sys_done = system(command); 116 | if (sys_done != 0) 117 | { 118 | cerr << "system command to confirm directory "+path+" exists has failed."; 119 | abort(); 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /tools/ptlcalls/util.cpp: -------------------------------------------------------------------------------- 1 | /********************************************************************************* 2 | * Copyright (c) 2010-2011, 3 | * Jim Stevens, Paul Tschirhart, Ishwar Singh Bhati, Mu-Tien Chang, Peter Enns, 4 | * Elliott Cooper-Balis, Paul Rosenfeld, Bruce Jacob 5 | * University of Maryland 6 | * Contact: jims [at] cs [dot] umd [dot] edu 7 | * All rights reserved. 8 | * 9 | * Redistribution and use in source and binary forms, with or without 10 | * modification, are permitted provided that the following conditions are met: 11 | * 12 | * * Redistributions of source code must retain the above copyright notice, 13 | * this list of conditions and the following disclaimer. 14 | * 15 | * * Redistributions in binary form must reproduce the above copyright notice, 16 | * this list of conditions and the following disclaimer in the documentation 17 | * and/or other materials provided with the distribution. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | *********************************************************************************/ 30 | 31 | #include "util.h" 32 | 33 | void convert_uint64_t(uint64_t &var, string value, string infostring) 34 | { 35 | // Check that each character in value is a digit. 36 | for(size_t i = 0; i < value.size(); i++) 37 | { 38 | if(!isdigit(value[i])) 39 | { 40 | cerr << "ERROR: Non-digit character found: " << infostring << " : " << value << "\n"; 41 | abort(); 42 | } 43 | } 44 | 45 | // Convert it 46 | stringstream ss; 47 | ss << value; 48 | ss >> var; 49 | } 50 | 51 | string strip(string input, string chars) 52 | { 53 | size_t pos; 54 | 55 | // Strip front. 56 | pos = input.find_first_not_of(chars); 57 | input.erase(0, pos); 58 | 59 | // Strip back. 60 | pos = input.find_last_not_of(chars); 61 | input.erase(pos+1); 62 | 63 | return input; 64 | } 65 | 66 | 67 | list split(string input, string chars, size_t maxsplit) 68 | { 69 | list ret; 70 | 71 | string cur = input; 72 | 73 | size_t pos = 0; 74 | 75 | if (maxsplit == 0) 76 | maxsplit = 1; 77 | 78 | while (!cur.empty()) 79 | { 80 | if (ret.size() == (maxsplit-1)) 81 | { 82 | ret.push_back(cur); 83 | return ret; 84 | } 85 | 86 | pos = cur.find_first_of(chars); 87 | string tmp = cur.substr(0, pos); 88 | ret.push_back(tmp); 89 | 90 | 91 | if (pos == string::npos) 92 | cur.erase(); 93 | else 94 | { 95 | // Skip ahead to the next non-split char 96 | size_t new_pos = cur.find_first_not_of(chars, pos); 97 | //cur.erase(0, pos+1); 98 | cur.erase(0, new_pos); 99 | } 100 | } 101 | 102 | // If not at npos, then there is still an extra empty string at the end. 103 | if (pos != string::npos) 104 | { 105 | ret.push_back(""); 106 | } 107 | 108 | return ret; 109 | } 110 | 111 | void confirm_directory_exists(string path) 112 | { 113 | string command_str = "test -e "+path+" || mkdir "+path; 114 | const char * command = command_str.c_str(); 115 | int sys_done = system(command); 116 | if (sys_done != 0) 117 | { 118 | cerr << "system command to confirm directory "+path+" exists has failed."; 119 | abort(); 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /old/TraceBasedSim_force_writeback.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * DRAMSim2: A Cycle Accurate DRAM simulator 3 | * 4 | * Copyright (C) 2010 Elliott Cooper-Balis 5 | * Paul Rosenfeld 6 | * Bruce Jacob 7 | * University of Maryland 8 | * 9 | * This program is free software: you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License as published by 11 | * the Free Software Foundation, either version 3 of the License, or 12 | * (at your option) any later version. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with this program. If not, see . 21 | * 22 | *****************************************************************************/ 23 | 24 | 25 | 26 | #include "TraceBasedSim.h" 27 | 28 | using namespace HybridSim; 29 | using namespace std; 30 | 31 | int complete = 0; 32 | 33 | int main() 34 | { 35 | printf("dramsim_test main()\n"); 36 | some_object obj; 37 | obj.add_one_and_run(); 38 | } 39 | 40 | 41 | void some_object::read_complete(uint id, uint64_t address, uint64_t clock_cycle) 42 | { 43 | printf("[Callback] read complete: %d 0x%lx cycle=%lu\n", id, address, clock_cycle); 44 | complete++; 45 | } 46 | 47 | void some_object::write_complete(uint id, uint64_t address, uint64_t clock_cycle) 48 | { 49 | printf("[Callback] write complete: %d 0x%lx cycle=%lu\n", id, address, clock_cycle); 50 | complete++; 51 | } 52 | 53 | /* FIXME: this may be broken, currently */ 54 | void power_callback(double a, double b, double c, double d) 55 | { 56 | printf("power callback: %0.3f, %0.3f, %0.3f, %0.3f\n",a,b,c,d); 57 | } 58 | 59 | int some_object::add_one_and_run() 60 | { 61 | /* pick a DRAM part to simulate */ 62 | HybridSystem *mem = new HybridSystem(1); 63 | 64 | /* create and register our callback functions */ 65 | Callback_t *read_cb = new Callback(this, &some_object::read_complete); 66 | Callback_t *write_cb = new Callback(this, &some_object::write_complete); 67 | mem->RegisterCallbacks(read_cb, write_cb, power_callback); 68 | 69 | const int LEN = 65; 70 | //uint64_t addr[] = {0x50000, 0x90012}; 71 | //int rd[] = {1, 0}; 72 | 73 | for (int i=0; i 64 | 65 | The trace file format is an ASCII file with each access in the trace as a separate 66 | line. Each access consists of a cycle number, an operation type (0 for read, 1 for write), 67 | and an byte address for the memory access (addresses should be aligned to 64 bytes). 68 | 69 | ---------------------------------------------------------------------- 70 | Repository Management: 71 | 72 | This repo follows a standard git branching scheme. 73 | 74 | * master - stable branch 75 | * dev - unstable development branch 76 | 77 | All other branches are feature branches. Some may be orphans and some 78 | may eventually be merged into dev. The master branch will only merge 79 | changes from dev after we are satisfied they are stable. 80 | 81 | Tags with format vX.Y.Z are considered releases of stable versions. 82 | All other tags are considered experimental. 83 | 84 | The following versions of NVDIMMSim and DRAMSim2 will be kept compatible with 85 | the master branch of HybridSim... 86 | 87 | https://github.com/jimstevens2001/NVDIMMSim/tree/stable 88 | https://github.com/jimstevens2001/DRAMSim2 89 | 90 | Note that the HybridSim-compatible version of DRAMSim2 is not necsesarily 91 | the same as the mainline version of DRAMSim2 maintained here: 92 | https://github.com/dramninjasUMD/DRAMSim2 93 | 94 | Additionally, tagged releases across the three will be kept consistent in terms 95 | of version numbers. 96 | 97 | ---------------------------------------------------------------------- 98 | Software License: 99 | This software is open-source and is released under the BSD license. Please 100 | see the file LICENSE for a copy of the license. 101 | -------------------------------------------------------------------------------- /tools/perfect_prefetching/analyze_traces.py: -------------------------------------------------------------------------------- 1 | # This tool generates prefetch data from a HybridSim format trace. 2 | 3 | 4 | import sys 5 | 6 | ADJUSTMENT = 400 # Set the adjustment to prevent premature evictions in non-deterministic runs (e.g. marss) 7 | # If fully deterministic, set this to 0. 8 | 9 | SET_SIZE = 64 10 | PAGE_SIZE = 4096 11 | CACHE_PAGES = 131072 12 | TOTAL_PAGES = 2097152 13 | BURST_SIZE = 64 14 | 15 | NUM_SETS = CACHE_PAGES / SET_SIZE 16 | 17 | def PAGE_NUMBER(addr): 18 | return addr / PAGE_SIZE 19 | def PAGE_ADDRESS(addr): 20 | return ((addr / PAGE_SIZE) * PAGE_SIZE) 21 | def PAGE_OFFSET(addr): 22 | return (addr % PAGE_SIZE) 23 | def SET_INDEX(addr): 24 | return (PAGE_NUMBER(addr) % NUM_SETS) 25 | def TAG(addr): 26 | return (PAGE_NUMBER(addr) / NUM_SETS) 27 | def FLASH_ADDRESS(tag, set_num): 28 | return ((tag * NUM_SETS + set_num) * PAGE_SIZE) 29 | def ALIGN(addr): 30 | return (((addr / BURST_SIZE) * BURST_SIZE) % (TOTAL_PAGES * PAGE_SIZE)) 31 | 32 | 33 | def process_tracefile(filename): 34 | tracefile = open(filename, 'r') 35 | 36 | 37 | counter = 0 38 | cnt = {} 39 | cache = {} 40 | prefetch = {} 41 | init = {} 42 | 43 | for i in range(NUM_SETS): 44 | cnt[i] = 0 # This counts the access number to each set (which is used to trigger prefetches) 45 | cache[i] = [] # This holds SET_SIZE pairs of (access number, page) in LRU order (the one at the end gets evicted on misses). 46 | prefetch[i] = [] # This holds triples of (access number, old page, new page) to prefetch. These are triggered immediately after a set is no longer needed. 47 | init[i] = [] # The initial pages in each cache set. 48 | 49 | 50 | # The general algorithm here is that whenever a miss occurs, we know when a particular evicted page is no longer needed (by using its access number). 51 | # Since we have the last access number a particular page was actually used, we can evict the page immediately after that access rather than waiting 52 | # until later. 53 | # The prefetch lists (one for each set) contains all of the data necessary to do this early eviction and prefetching. 54 | 55 | while(1): 56 | line = tracefile.readline() 57 | if line == '': 58 | break 59 | 60 | [cycle, op, address] = [int(i) for i in line.strip().split()] 61 | address = ALIGN(address) 62 | 63 | page = PAGE_ADDRESS(address) 64 | set_index = SET_INDEX(address) 65 | 66 | 67 | # Check for a hit. 68 | set_pages = [i for (i,j) in cache[set_index]] 69 | if set_pages.count(page) == 1: 70 | # We hit. 71 | 72 | # Find and delete the old cache entry for this page. 73 | page_index = set_pages.index(page) 74 | del cache[set_index][page_index] 75 | 76 | else: 77 | # We missed. 78 | 79 | if len(cache[set_index]) == SET_SIZE: 80 | # Evict the last thing in the cache (index 63). 81 | evicted = cache[set_index].pop(63) 82 | (evicted_page, access_number) = evicted 83 | 84 | # Update the prefetch list. 85 | prefetch[set_index].append((access_number, evicted_page, page)) 86 | 87 | else: 88 | # The cache set isn't full yet, so just put this at the front of the list and do not evict anything. 89 | init[set_index].append(page) 90 | 91 | # Insert the new entry at the beginning of the list (for LRU). 92 | cache[set_index].insert(0, (page, cnt[set_index])) 93 | 94 | 95 | # Increment the counter for the current set. 96 | cnt[set_index] += 1 97 | counter += 1 98 | 99 | if counter % 100000 == 0: 100 | print counter 101 | 102 | # Done. Now write this to a file. 103 | outFile = open('prefetch_data.txt', 'w') 104 | outFile.write('NUM_SETS '+str(NUM_SETS)+'\n\n\n') 105 | for i in range(NUM_SETS): 106 | outFile.write('SET '+str(i)+' '+str(len(prefetch[i]))+'\n') 107 | # outFile.write(str(prefetch[i])+'\n\n') 108 | for j in range(len(prefetch[i])): 109 | access_number = str(prefetch[i][j][0]+ADJUSTMENT) 110 | evicted_page = str(prefetch[i][j][1]) 111 | prefetch_page = str(prefetch[i][j][2]) 112 | outFile.write(access_number+' '+evicted_page+' '+prefetch_page+'\n'); 113 | outFile.write('\n\n') 114 | outFile.close() 115 | 116 | 117 | # Save cache state table. 118 | outFile = open('prefetch_cache_state.txt', 'w') 119 | outFile.write(str(PAGE_SIZE)+' '+str(SET_SIZE)+' '+str(CACHE_PAGES)+' '+str(TOTAL_PAGES)+'\n') 120 | for i in range(CACHE_PAGES): 121 | cache_addr = i*PAGE_SIZE 122 | set_index = SET_INDEX(cache_addr) 123 | 124 | # If there is another address to output in this file. 125 | if len(init[set_index]) > 0: 126 | cur_page = init[set_index].pop(0) 127 | tag = TAG(cur_page) 128 | ts = i/NUM_SETS 129 | 130 | # order to output is cache_addr 1 1 tag 0 ts 131 | outFile.write(str(cache_addr)+' 1 1 '+str(tag)+' 0 '+str(ts)+'\n') 132 | 133 | outFile.close() 134 | 135 | 136 | process_tracefile(sys.argv[1]) 137 | 138 | -------------------------------------------------------------------------------- /traces/2_seq_page.txt: -------------------------------------------------------------------------------- 1 | 0 0 536870912 2 | 100 0 1610612736 3 | 200 0 536875008 4 | 300 0 1610616832 5 | 400 0 536879104 6 | 500 0 1610620928 7 | 600 0 536883200 8 | 700 0 1610625024 9 | 800 0 536887296 10 | 900 0 1610629120 11 | 1000 0 536891392 12 | 1100 0 1610633216 13 | 1200 0 536895488 14 | 1300 0 1610637312 15 | 1400 0 536899584 16 | 1500 0 1610641408 17 | 1600 0 536903680 18 | 1700 0 1610645504 19 | 1800 0 536907776 20 | 1900 0 1610649600 21 | 2000 0 536911872 22 | 2100 0 1610653696 23 | 2200 0 536915968 24 | 2300 0 1610657792 25 | 2400 0 536920064 26 | 2500 0 1610661888 27 | 2600 0 536924160 28 | 2700 0 1610665984 29 | 2800 0 536928256 30 | 2900 0 1610670080 31 | 3000 0 536932352 32 | 3100 0 1610674176 33 | 3200 0 536936448 34 | 3300 0 1610678272 35 | 3400 0 536940544 36 | 3500 0 1610682368 37 | 3600 0 536944640 38 | 3700 0 1610686464 39 | 3800 0 536948736 40 | 3900 0 1610690560 41 | 4000 0 536952832 42 | 4100 0 1610694656 43 | 4200 0 536956928 44 | 4300 0 1610698752 45 | 4400 0 536961024 46 | 4500 0 1610702848 47 | 4600 0 536965120 48 | 4700 0 1610706944 49 | 4800 0 536969216 50 | 4900 0 1610711040 51 | 5000 0 536973312 52 | 5100 0 1610715136 53 | 5200 0 536977408 54 | 5300 0 1610719232 55 | 5400 0 536981504 56 | 5500 0 1610723328 57 | 5600 0 536985600 58 | 5700 0 1610727424 59 | 5800 0 536989696 60 | 5900 0 1610731520 61 | 6000 0 536993792 62 | 6100 0 1610735616 63 | 6200 0 536997888 64 | 6300 0 1610739712 65 | 6400 0 537001984 66 | 6500 0 1610743808 67 | 6600 0 537006080 68 | 6700 0 1610747904 69 | 6800 0 537010176 70 | 6900 0 1610752000 71 | 7000 0 537014272 72 | 7100 0 1610756096 73 | 7200 0 537018368 74 | 7300 0 1610760192 75 | 7400 0 537022464 76 | 7500 0 1610764288 77 | 7600 0 537026560 78 | 7700 0 1610768384 79 | 7800 0 537030656 80 | 7900 0 1610772480 81 | 8000 0 537034752 82 | 8100 0 1610776576 83 | 8200 0 537038848 84 | 8300 0 1610780672 85 | 8400 0 537042944 86 | 8500 0 1610784768 87 | 8600 0 537047040 88 | 8700 0 1610788864 89 | 8800 0 537051136 90 | 8900 0 1610792960 91 | 9000 0 537055232 92 | 9100 0 1610797056 93 | 9200 0 537059328 94 | 9300 0 1610801152 95 | 9400 0 537063424 96 | 9500 0 1610805248 97 | 9600 0 537067520 98 | 9700 0 1610809344 99 | 9800 0 537071616 100 | 9900 0 1610813440 101 | 10000 0 537075712 102 | 10100 0 1610817536 103 | 10200 0 537079808 104 | 10300 0 1610821632 105 | 10400 0 537083904 106 | 10500 0 1610825728 107 | 10600 0 537088000 108 | 10700 0 1610829824 109 | 10800 0 537092096 110 | 10900 0 1610833920 111 | 11000 0 537096192 112 | 11100 0 1610838016 113 | 11200 0 537100288 114 | 11300 0 1610842112 115 | 11400 0 537104384 116 | 11500 0 1610846208 117 | 11600 0 537108480 118 | 11700 0 1610850304 119 | 11800 0 537112576 120 | 11900 0 1610854400 121 | 12000 0 537116672 122 | 12100 0 1610858496 123 | 12200 0 537120768 124 | 12300 0 1610862592 125 | 12400 0 537124864 126 | 12500 0 1610866688 127 | 12600 0 537128960 128 | 12700 0 1610870784 129 | 12800 0 537133056 130 | 12900 0 1610874880 131 | 13000 0 537137152 132 | 13100 0 1610878976 133 | 13200 0 537141248 134 | 13300 0 1610883072 135 | 13400 0 537145344 136 | 13500 0 1610887168 137 | 13600 0 537149440 138 | 13700 0 1610891264 139 | 13800 0 537153536 140 | 13900 0 1610895360 141 | 14000 0 537157632 142 | 14100 0 1610899456 143 | 14200 0 537161728 144 | 14300 0 1610903552 145 | 14400 0 537165824 146 | 14500 0 1610907648 147 | 14600 0 537169920 148 | 14700 0 1610911744 149 | 14800 0 537174016 150 | 14900 0 1610915840 151 | 15000 0 537178112 152 | 15100 0 1610919936 153 | 15200 0 537182208 154 | 15300 0 1610924032 155 | 15400 0 537186304 156 | 15500 0 1610928128 157 | 15600 0 537190400 158 | 15700 0 1610932224 159 | 15800 0 537194496 160 | 15900 0 1610936320 161 | 16000 0 537198592 162 | 16100 0 1610940416 163 | 16200 0 537202688 164 | 16300 0 1610944512 165 | 16400 0 537206784 166 | 16500 0 1610948608 167 | 16600 0 537210880 168 | 16700 0 1610952704 169 | 16800 0 537214976 170 | 16900 0 1610956800 171 | 17000 0 537219072 172 | 17100 0 1610960896 173 | 17200 0 537223168 174 | 17300 0 1610964992 175 | 17400 0 537227264 176 | 17500 0 1610969088 177 | 17600 0 537231360 178 | 17700 0 1610973184 179 | 17800 0 537235456 180 | 17900 0 1610977280 181 | 18000 0 537239552 182 | 18100 0 1610981376 183 | 18200 0 537243648 184 | 18300 0 1610985472 185 | 18400 0 537247744 186 | 18500 0 1610989568 187 | 18600 0 537251840 188 | 18700 0 1610993664 189 | 18800 0 537255936 190 | 18900 0 1610997760 191 | 19000 0 537260032 192 | 19100 0 1611001856 193 | 19200 0 537264128 194 | 19300 0 1611005952 195 | 19400 0 537268224 196 | 19500 0 1611010048 197 | 19600 0 537272320 198 | 19700 0 1611014144 199 | 19800 0 537276416 200 | 19900 0 1611018240 201 | -------------------------------------------------------------------------------- /tools/perfect_prefetching/analyze_traces_complex.py: -------------------------------------------------------------------------------- 1 | # This tool generates a very detailed analysis of prefetch data from a HybridSim format trace. 2 | # THIS IS NOT A VALID PREFETCH DATA FORMAT. IT IS SIMPLY MEANT FOR STUDY. 3 | 4 | 5 | import sys 6 | 7 | SET_SIZE = 64 8 | PAGE_SIZE = 4096 9 | CACHE_PAGES = 131072 10 | TOTAL_PAGES = 2097152 11 | BURST_SIZE = 64 12 | 13 | NUM_SETS = CACHE_PAGES / SET_SIZE 14 | 15 | def PAGE_NUMBER(addr): 16 | return addr / PAGE_SIZE 17 | def PAGE_ADDRESS(addr): 18 | return ((addr / PAGE_SIZE) * PAGE_SIZE) 19 | def PAGE_OFFSET(addr): 20 | return (addr % PAGE_SIZE) 21 | def SET_INDEX(addr): 22 | return (PAGE_NUMBER(addr) % NUM_SETS) 23 | def TAG(addr): 24 | return (PAGE_NUMBER(addr) / NUM_SETS) 25 | def FLASH_ADDRESS(tag, set_num): 26 | return ((tag * NUM_SETS + set_num) * PAGE_SIZE) 27 | def ALIGN(addr): 28 | return (((addr / BURST_SIZE) * BURST_SIZE) % (TOTAL_PAGES * PAGE_SIZE)) 29 | 30 | 31 | def process_tracefile(filename): 32 | tracefile = open(filename, 'r') 33 | 34 | 35 | counter = 0 36 | cnt = {} 37 | cache = {} 38 | prefetch = {} 39 | init = {} 40 | 41 | for i in range(NUM_SETS): 42 | cnt[i] = 0 # This counts the access number to each set (which is used to trigger prefetches) 43 | cache[i] = [] # This holds SET_SIZE pairs of (access number, page) in LRU order (the one at the end gets evicted on misses). 44 | prefetch[i] = [] # This holds triples of (access number, old page, new page) to prefetch. These are triggered immediately after a set is no longer needed. 45 | init[i] = [] # The initial pages in each cache set. 46 | 47 | 48 | # The general algorithm here is that whenever a miss occurs, we know when a particular evicted page is no longer needed (by using its access number). 49 | # Since we have the last access number a particular page was actually used, we can evict the page immediately after that access rather than waiting 50 | # until later. 51 | # The prefetch lists (one for each set) contains all of the data necessary to do this early eviction and prefetching. 52 | 53 | while(1): 54 | line = tracefile.readline() 55 | if line == '': 56 | break 57 | 58 | [cycle, op, address] = [int(i) for i in line.strip().split()] 59 | address = ALIGN(address) 60 | 61 | page = PAGE_ADDRESS(address) 62 | set_index = SET_INDEX(address) 63 | 64 | 65 | # Check for a hit. 66 | set_pages = [i for (i,j,k) in cache[set_index]] 67 | if set_pages.count(page) == 1: 68 | # We hit. 69 | 70 | # Find and delete the old cache entry for this page. 71 | page_index = set_pages.index(page) 72 | del cache[set_index][page_index] 73 | 74 | else: 75 | # We missed. 76 | 77 | if len(cache[set_index]) == SET_SIZE: 78 | # Evict the last thing in the cache (index 63). 79 | evicted = cache[set_index].pop(63) 80 | (evicted_page, access_number, old_cycle) = evicted 81 | 82 | # Update the prefetch list. 83 | prefetch[set_index].append((access_number, evicted_page, page, cnt[set_index], old_cycle, cycle)) 84 | 85 | else: 86 | # The cache set isn't full yet, so just put this at the front of the list and do not evict anything. 87 | init[set_index].append(page) 88 | 89 | # Insert the new entry at the beginning of the list (for LRU). 90 | cache[set_index].insert(0, (page, cnt[set_index], cycle)) 91 | 92 | 93 | # Increment the counter for the current set. 94 | cnt[set_index] += 1 95 | counter += 1 96 | 97 | if counter % 100000 == 0: 98 | print counter 99 | 100 | # Done. Now write this to a file. 101 | min_diff = 100000000000 # Just start with a large number 102 | min_access_diff = 100000000000 # Just start with a large number 103 | outFile = open('prefetch_data.txt', 'w') 104 | outFile.write('NUM_SETS '+str(NUM_SETS)+'\n\n\n') 105 | for i in range(NUM_SETS): 106 | outFile.write('SET '+str(i)+' '+str(len(prefetch[i]))+'\n') 107 | # outFile.write(str(prefetch[i])+'\n\n') 108 | for j in range(len(prefetch[i])): 109 | access_number = str(prefetch[i][j][0]) 110 | evicted_page = str(prefetch[i][j][1]) 111 | prefetch_page = str(prefetch[i][j][2]) 112 | new_access_number = str(prefetch[i][j][3]) 113 | old_cycle = str(prefetch[i][j][4]) 114 | new_cycle = str(prefetch[i][j][5]) 115 | cycle_diff = int(new_cycle) - int(old_cycle) 116 | access_diff = int(new_access_number) - int(access_number) 117 | if cycle_diff < min_diff: 118 | min_diff = cycle_diff 119 | if access_diff < min_access_diff: 120 | min_access_diff = access_diff 121 | outFile.write('accesses:('+access_number+', '+new_access_number+') pages:('+evicted_page+', '+prefetch_page+') cycles:('+old_cycle+', '+new_cycle+') diff: '+str(cycle_diff)+'\n'); 122 | outFile.write('\n\n') 123 | outFile.close() 124 | print 'min_diff:',min_diff 125 | print 'min_access_diff:',min_access_diff 126 | 127 | 128 | # Save cache state table. 129 | outFile = open('prefetch_cache_state.txt', 'w') 130 | outFile.write(str(PAGE_SIZE)+' '+str(SET_SIZE)+' '+str(CACHE_PAGES)+' '+str(TOTAL_PAGES)+'\n') 131 | for i in range(CACHE_PAGES): 132 | cache_addr = i*PAGE_SIZE 133 | set_index = SET_INDEX(cache_addr) 134 | 135 | # If there is another address to output in this file. 136 | if len(init[set_index]) > 0: 137 | cur_page = init[set_index].pop(0) 138 | tag = TAG(cur_page) 139 | ts = i/NUM_SETS 140 | 141 | # order to output is cache_addr 1 1 tag 0 ts 142 | outFile.write(str(cache_addr)+' 1 1 '+str(tag)+' 0 '+str(ts)+'\n') 143 | 144 | outFile.close() 145 | 146 | 147 | process_tracefile(sys.argv[1]) 148 | 149 | -------------------------------------------------------------------------------- /old/trace based tests/TraceBasedSim.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * DRAMSim2: A Cycle Accurate DRAM simulator 3 | * 4 | * Copyright (C) 2010 Elliott Cooper-Balis 5 | * Paul Rosenfeld 6 | * Bruce Jacob 7 | * University of Maryland 8 | * 9 | * This program is free software: you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License as published by 11 | * the Free Software Foundation, either version 3 of the License, or 12 | * (at your option) any later version. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with this program. If not, see . 21 | * 22 | *****************************************************************************/ 23 | 24 | 25 | 26 | #include "TraceBasedSim.h" 27 | 28 | using namespace HybridSim; 29 | using namespace std; 30 | 31 | int complete = 0; 32 | 33 | int main() 34 | { 35 | printf("hybridsim_test main()\n"); 36 | some_object obj; 37 | obj.add_one_and_run(); 38 | } 39 | 40 | 41 | void some_object::read_complete(uint id, uint64_t address, uint64_t clock_cycle) 42 | { 43 | printf("[Callback] read complete: %d 0x%lx cycle=%lu\n", id, address, clock_cycle); 44 | complete++; 45 | } 46 | 47 | void some_object::write_complete(uint id, uint64_t address, uint64_t clock_cycle) 48 | { 49 | printf("[Callback] write complete: %d 0x%lx cycle=%lu\n", id, address, clock_cycle); 50 | complete++; 51 | } 52 | 53 | /* FIXME: this may be broken, currently */ 54 | void power_callback(double a, double b, double c, double d) 55 | { 56 | printf("power callback: %0.3f, %0.3f, %0.3f, %0.3f\n",a,b,c,d); 57 | } 58 | 59 | int some_object::add_one_and_run() 60 | { 61 | /* pick a DRAM part to simulate */ 62 | HybridSystem *mem = new HybridSystem(1); 63 | //MemorySystem *mem = new MemorySystem(0, "ini/DDR3_micron_32M_8B_x8_sg15.ini", "ini/system.ini", "", ""); 64 | 65 | 66 | /* create and register our callback functions */ 67 | typedef CallbackBase Callback_t; 68 | Callback_t *read_cb = new Callback(this, &some_object::read_complete); 69 | Callback_t *write_cb = new Callback(this, &some_object::write_complete); 70 | mem->RegisterCallbacks(read_cb, write_cb, power_callback); 71 | 72 | srand (time(NULL)); 73 | 74 | mem->addTransaction(false, 140708070030063); 75 | for (uint64_t i=0; i<10000; i++) 76 | { 77 | mem->update(); 78 | } 79 | 80 | 81 | cout << "Preparing transactions to preload cache with data...\n"; 82 | uint64_t num_init = 10000; 83 | for (uint64_t i=0; iaddTransaction(t); 88 | if (i%10000 == 0) 89 | cout << i << "/" << num_init << endl; 90 | } 91 | cout << "Running transactions to preload cache with data...\n"; 92 | int factor = 1000; 93 | for (uint64_t i=0; iupdate(); 96 | if (i%1000000 == 0) 97 | { 98 | cout << i << "/" << num_init*factor << endl; 99 | } 100 | } 101 | 102 | uint64_t cur_addr = 0; 103 | 104 | const uint64_t NUM_ACCESSES = 1000; 105 | const int MISS_RATE = 10; 106 | 107 | cout << "Starting miss rate test...\n"; 108 | for (uint64_t i=0; iget_valid_pages().size() == 0) 118 | // want_hit = false; 119 | 120 | if (want_hit) 121 | cur_addr = mem->get_hit(); 122 | else 123 | cur_addr = (rand() % TOTAL_PAGES) * PAGE_SIZE; 124 | 125 | cout << mem->currentClockCycle << ": want_hit=" << want_hit << " cur_addr=" << cur_addr << endl; 126 | 127 | // Pick the address that will give a hit or a miss. 128 | int k=0; 129 | while(mem->is_hit(cur_addr) != want_hit) 130 | { 131 | cur_addr = (rand() % TOTAL_PAGES) * PAGE_SIZE; 132 | k++; 133 | cout << "k=" << k << " want_hit=" << want_hit << " cur_addr=" << cur_addr << " is_hit=" << mem->is_hit(cur_addr) << "\n"; 134 | 135 | } 136 | //cur_addr = (cur_addr + PAGE_SIZE) % (TOTAL_PAGES * PAGE_SIZE); 137 | 138 | 139 | DRAMSim::Transaction t = DRAMSim::Transaction(type, cur_addr, NULL); 140 | mem->addTransaction(t); 141 | 142 | #if DEBUG_CACHE 143 | cout << "\n\tAdded transaction " << i << " of type=" << type << " addr=" << cur_addr << " set=" << SET_INDEX(cur_addr) 144 | << " tag=" << TAG(cur_addr) << endl; 145 | #endif 146 | 147 | for (int j=0; jupdate(); 150 | } 151 | } 152 | 153 | 154 | for (int i=0; i<1000000; i++) 155 | { 156 | mem->update(); 157 | } 158 | 159 | 160 | cout << "\n\n" << mem->currentClockCycle << ": completed " << complete << "\n\n"; 161 | cout << "dram_pending=" << mem->dram_pending.size() << " flash_pending=" << mem->flash_pending.size() << "\n\n"; 162 | cout << "dram_queue=" << mem->dram_queue.size() << " flash_queue=" << mem->flash_queue.size() << "\n\n"; 163 | cout << "pending_pages=" << mem->pending_pages.size() << "\n\n"; 164 | 165 | return 0; 166 | } 167 | 168 | -------------------------------------------------------------------------------- /old/trace based tests/FlashWriteBackTest.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * DRAMSim2: A Cycle Accurate DRAM simulator 3 | * 4 | * Copyright (C) 2010 Elliott Cooper-Balis 5 | * Paul Rosenfeld 6 | * Bruce Jacob 7 | * University of Maryland 8 | * 9 | * This program is free software: you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License as published by 11 | * the Free Software Foundation, either version 3 of the License, or 12 | * (at your option) any later version. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with this program. If not, see . 21 | * 22 | *****************************************************************************/ 23 | 24 | 25 | 26 | #include "TraceBasedSim.h" 27 | 28 | using namespace HybridSim; 29 | using namespace std; 30 | 31 | int complete = 0; 32 | 33 | int main() 34 | { 35 | printf("hybridsim_test main()\n"); 36 | some_object obj; 37 | obj.add_one_and_run(); 38 | } 39 | 40 | 41 | void some_object::read_complete(uint id, uint64_t address, uint64_t clock_cycle) 42 | { 43 | printf("[Callback] read complete: %d 0x%lx cycle=%lu\n", id, address, clock_cycle); 44 | complete++; 45 | } 46 | 47 | void some_object::write_complete(uint id, uint64_t address, uint64_t clock_cycle) 48 | { 49 | printf("[Callback] write complete: %d 0x%lx cycle=%lu\n", id, address, clock_cycle); 50 | complete++; 51 | } 52 | 53 | /* FIXME: this may be broken, currently */ 54 | void power_callback(double a, double b, double c, double d) 55 | { 56 | printf("power callback: %0.3f, %0.3f, %0.3f, %0.3f\n",a,b,c,d); 57 | } 58 | 59 | int some_object::add_one_and_run() 60 | { 61 | /* pick a DRAM part to simulate */ 62 | HybridSystem *mem = new HybridSystem(1); 63 | //MemorySystem *mem = new MemorySystem(0, "ini/DDR3_micron_32M_8B_x8_sg15.ini", "ini/system.ini", "", ""); 64 | 65 | 66 | /* create and register our callback functions */ 67 | typedef CallbackBase Callback_t; 68 | Callback_t *read_cb = new Callback(this, &some_object::read_complete); 69 | Callback_t *write_cb = new Callback(this, &some_object::write_complete); 70 | mem->RegisterCallbacks(read_cb, write_cb, power_callback); 71 | 72 | srand (time(NULL)); 73 | 74 | mem->addTransaction(false, 140708070030063); 75 | for (uint64_t i=0; i<10000; i++) 76 | { 77 | mem->update(); 78 | } 79 | 80 | 81 | cout << "Preparing transactions to preload cache with data...\n"; 82 | uint64_t num_init = 10000; 83 | for (uint64_t i=0; iaddTransaction(t); 88 | if (i%10000 == 0) 89 | cout << i << "/" << num_init << endl; 90 | } 91 | cout << "Running transactions to preload cache with data...\n"; 92 | int factor = 1000; 93 | for (uint64_t i=0; iupdate(); 96 | if (i%1000000 == 0) 97 | { 98 | cout << i << "/" << num_init*factor << endl; 99 | } 100 | } 101 | 102 | uint64_t cur_addr = 0; 103 | 104 | const uint64_t NUM_ACCESSES = 100; 105 | const int MISS_RATE = 10; 106 | 107 | cout << "Starting flash test...\n"; 108 | cout << "triggering writebacks to flash..." << endl; 109 | for (uint64_t i=0; iaddTransaction(t); 117 | 118 | #if DEBUG_CACHE 119 | cout << "\n\tAdded transaction " << i << " of type=" << type << " addr=" << cur_addr << " set=" << SET_INDEX(cur_addr) 120 | << " tag=" << TAG(cur_addr) << endl; 121 | #endif 122 | 123 | // TODO: not sure this update factor is correct for this test 124 | for (int j=0; jupdate(); 127 | } 128 | } 129 | 130 | curr_addr = 0; 131 | 132 | cout << "reading from flash... hopefully" << endl; 133 | for (uint64_t i=0; iaddTransaction(t); 141 | 142 | #if DEBUG_CACHE 143 | cout << "\n\tAdded transaction " << i << " of type=" << type << " addr=" << cur_addr << " set=" << SET_INDEX(cur_addr) 144 | << " tag=" << TAG(cur_addr) << endl; 145 | #endif 146 | 147 | // TODO: not sure this update factor is correct for this test 148 | for (int j=0; jupdate(); 151 | } 152 | } 153 | 154 | 155 | for (int i=0; i<1000000; i++) 156 | { 157 | mem->update(); 158 | } 159 | 160 | 161 | cout << "\n\n" << mem->currentClockCycle << ": completed " << complete << "\n\n"; 162 | cout << "dram_pending=" << mem->dram_pending.size() << " flash_pending=" << mem->flash_pending.size() << "\n\n"; 163 | cout << "dram_queue=" << mem->dram_queue.size() << " flash_queue=" << mem->flash_queue.size() << "\n\n"; 164 | cout << "pending_pages=" << mem->pending_pages.size() << "\n\n"; 165 | 166 | return 0; 167 | } 168 | 169 | -------------------------------------------------------------------------------- /tools/sweep_scripts/ini/prefetch.h: -------------------------------------------------------------------------------- 1 | #ifndef HYBRIDSYSTEM_CONFIG_H 2 | #define HYBRIDSYSTEM_CONFIG_H 3 | 4 | // Temporary prefetch flags. 5 | #define ENABLE_PREFETCHING 1 6 | #define PREFETCH_FILE "traces/prefetch_data.txt" 7 | 8 | // Debug flags. 9 | 10 | // Lots of output during cache operations. Goes to stdout. 11 | #define DEBUG_CACHE 0 12 | 13 | // Lots of output for debugging logging operations. Goes to debug.log. 14 | #define DEBUG_LOGGER 0 15 | 16 | // Outputs the victim selection process during each eviction. Goes to debug_victim.log. 17 | #define DEBUG_VICTIM 0 18 | 19 | // Outputs the full trace of accesses sent to NVDIMM. Goes to nvdimm_trace.log. 20 | #define DEBUG_NVDIMM_TRACE 0 21 | 22 | // Outputs the full trace of accesses received by HybridSim. Goes to full_trace.log. 23 | #define DEBUG_FULL_TRACE 0 24 | 25 | 26 | // SINGLE_WORD only sends one transaction to the memories per page instead of PAGE_SIZE/BURST_SIZE 27 | // This is an old feature that may not work. 28 | #define SINGLE_WORD 0 29 | 30 | 31 | // C standard library and C++ STL includes. 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | 47 | // Include external interface for DRAMSim. 48 | #include 49 | 50 | // Additional things I reuse from DRAMSim repo (for internal use only). 51 | //#include 52 | #include 53 | using DRAMSim::SimulatorObject; 54 | //using DRAMSim::TransactionType; 55 | //using DRAMSim::DATA_READ; 56 | //using DRAMSim::DATA_WRITE; 57 | 58 | // Include external interface for NVDIMM. 59 | #include 60 | 61 | 62 | // Include the Transaction type (which is needed below). 63 | #include "Transaction.h" 64 | 65 | // Declare error printout (used to be brought in from DRAMSim). 66 | #define ERROR(str) std::cerr<<"[ERROR ("<<__FILE__<<":"<<__LINE__<<")]: "< 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | 47 | // Include external interface for DRAMSim. 48 | #include 49 | 50 | // Additional things I reuse from DRAMSim repo (for internal use only). 51 | //#include 52 | #include 53 | using DRAMSim::SimulatorObject; 54 | //using DRAMSim::TransactionType; 55 | //using DRAMSim::DATA_READ; 56 | //using DRAMSim::DATA_WRITE; 57 | 58 | // Include external interface for NVDIMM. 59 | #include 60 | 61 | 62 | // Include the Transaction type (which is needed below). 63 | #include "Transaction.h" 64 | 65 | // Declare error printout (used to be brought in from DRAMSim). 66 | #define ERROR(str) std::cerr<<"[ERROR ("<<__FILE__<<":"<<__LINE__<<")]: "<= (TOTAL_PAGES * PAGE_SIZE)) 73 | { 74 | cout << "ERROR: Address out of bounds" << endl; 75 | exit(1); 76 | } 77 | 78 | // Compute page number 79 | uint64_t page_number = addr / PAGE_SIZE; 80 | 81 | // Compute the set number and tag 82 | uint64_t set_index = page_number % NUM_SETS; 83 | uint64_t tag = page_number / NUM_SETS; 84 | 85 | // Compute all cache addresses for this set. 86 | list set_address_list; 87 | //cout << "set_address_list: "; 88 | for (uint64_t i=0; i::iterator it = set_address_list.begin(); it != set_address_list.end(); ++it) 103 | { 104 | cur_address = *it; 105 | if (cache.count(cur_address) == 0) 106 | { 107 | // If i is not allocated yet, allocate it. 108 | cache[cur_address] = *(new cache_line()); 109 | } 110 | 111 | cur_line = cache[cur_address]; 112 | 113 | //cout << cur_address << " " << hit << " " << cur_line.str() << endl; 114 | 115 | if (cur_line.valid && (cur_line.tag == tag)) 116 | { 117 | hit = true; 118 | cache_address = cur_address; 119 | cout << "FOUND: " << cur_address << " " << hit << " " << cur_line.str() << endl; 120 | break; 121 | } 122 | 123 | } 124 | 125 | cout << "page_number " << page_number << endl; 126 | cout << "set_index " << set_index << endl; 127 | cout << "tag " << tag << endl; 128 | 129 | if (hit) 130 | { 131 | cout << "HIT: cache_address " << cache_address << endl; 132 | } 133 | 134 | if (!hit) 135 | { 136 | // Select a victim offset within the set (LRU) 137 | uint64_t victim = *(set_address_list.begin()); 138 | int min_ts = -1; 139 | 140 | for (list::iterator it=set_address_list.begin(); it != set_address_list.end(); it++) 141 | { 142 | cur_address = *it; 143 | cache_line cur_line = cache[cur_address]; 144 | if ((cur_line.ts < min_ts) || (min_ts == -1)) 145 | { 146 | min_ts = cur_line.ts; 147 | victim = cur_address; 148 | } 149 | } 150 | 151 | cache_address = victim; 152 | 153 | cout << "MISS: victim is cache_address " << cache_address << endl; 154 | 155 | 156 | cur_line = cache[cache_address]; 157 | 158 | if (cur_line.dirty) 159 | { 160 | // Perform writeback 161 | uint64_t victim_flash_addr = (cur_line.tag * NUM_SETS + set_index) * PAGE_SIZE; 162 | flash[victim_flash_addr] = cur_line.data; 163 | cout << "writeback cache_address= " << cache_address << " (flash_addr, data)=("; 164 | cout << victim_flash_addr << ", " << cur_line.data << ")\n"; 165 | } 166 | 167 | if (op == OP_READ) 168 | { 169 | // Load the page from flash 170 | cur_line.data = flash[addr]; 171 | cur_line.tag = tag; 172 | cur_line.dirty = false; 173 | cur_line.valid = true; 174 | cur_line.ts = ts_counter; 175 | cache[cache_address] = cur_line; 176 | } 177 | } 178 | 179 | if (op == OP_WRITE) 180 | { 181 | cur_line.data = data; 182 | cur_line.tag = tag; 183 | cur_line.dirty = true; 184 | cur_line.valid = true; 185 | cur_line.ts = ts_counter; 186 | cache[cache_address] = cur_line; 187 | } 188 | 189 | cout << endl; 190 | 191 | return cur_line.data; 192 | 193 | } 194 | 195 | int main() 196 | { 197 | 198 | srand((unsigned int)time(NULL)); 199 | 200 | // Basic test 201 | //transaction(OP_WRITE, 0, 5); 202 | //cout << transaction(OP_READ, 0, 0) << endl; 203 | 204 | uint64_t TESTS = 1000000; 205 | list address_list; 206 | //uint64_t TESTS = TOTAL_PAGES; 207 | for (uint64_t i=0; i::iterator it = address_list.begin(); it != address_list.end(); ++it) 215 | { 216 | uint64_t i = *it; 217 | uint64_t x = transaction(OP_READ, i, 0); 218 | if (i != x) 219 | { 220 | cout << "FAILED " << i << " " << x << endl; 221 | exit(1); 222 | } 223 | } 224 | cout << "PASSED" << endl; 225 | 226 | return 0; 227 | } 228 | -------------------------------------------------------------------------------- /tools/GraphGen.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | import matplotlib 4 | matplotlib.use('Agg') # To allow for running without X. 5 | import matplotlib.pyplot as plt 6 | 7 | import pprint 8 | 9 | FIGURE_CNT = 1 10 | 11 | def parse_file(logfile): 12 | section = '================================================================================' 13 | 14 | inFile = open(logfile, 'r') 15 | lines = inFile.readlines() 16 | inFile.close() 17 | lines = [line.strip() for line in lines] 18 | 19 | section_list = [] 20 | for i in range(len(lines)): 21 | if lines[i] == section: 22 | section_list.append(i) 23 | 24 | sections = {} 25 | sections['total'] = lines[0:section_list[0]-2] 26 | sections['epoch'] = lines[section_list[0]+5:section_list[1]] 27 | sections['miss'] = lines[section_list[1]+3:section_list[2]-2] 28 | sections['access'] = lines[section_list[2]+3:section_list[3]-2] 29 | sections['latency'] = lines[section_list[3]+4:section_list[4]-2] 30 | sections['sets'] = lines[section_list[4]+4:] 31 | 32 | return sections 33 | 34 | 35 | def parse_total(total_lines): 36 | sections = ['total', 'read', 'write'] 37 | total_dict = {} 38 | for j in sections: 39 | total_dict[j] = {} 40 | cur_section = 0 41 | 42 | for i in total_lines: 43 | if i == '': 44 | cur_section += 1 45 | continue 46 | tmp = i.split(':') 47 | key = tmp[0].strip() 48 | val = tmp[1].strip() 49 | if key.endswith('latency'): 50 | latency_vals = [v.strip(') ') for v in val.split('(')] 51 | total_dict[sections[cur_section]][key+' cycles'] = float(latency_vals[0].split(' ')[0]) 52 | total_dict[sections[cur_section]][key+' us'] = float(latency_vals[1].split(' ')[0]) 53 | else: 54 | try: 55 | # Try to parse it as an int. 56 | total_dict[sections[cur_section]][key] = int(val.split()[0]) 57 | except: 58 | # If that doesn't work, then parse it as a float. 59 | total_dict[sections[cur_section]][key] = float(val.split()[0]) 60 | 61 | return total_dict 62 | 63 | 64 | def parse_epoch(epoch_lines): 65 | epoch_section = '---------------------------------------------------' 66 | 67 | epoch_lines_list = [] 68 | cur_section = [] 69 | for i in epoch_lines: 70 | if i == epoch_section: 71 | epoch_lines_list.append(cur_section) 72 | cur_section = [] 73 | continue 74 | cur_section.append(i) 75 | 76 | epoch_list = [] 77 | for i in epoch_lines_list: 78 | epoch_list.append(parse_total(i[:-2])) 79 | 80 | return epoch_list 81 | 82 | 83 | 84 | def parse_misses(miss_lines): 85 | miss_list = [] 86 | for i in miss_lines: 87 | cur_dict = {} 88 | tmp = i.split(':') 89 | cur_dict['address'] = int(tmp[0], 16) 90 | data = tmp[1].split(';') 91 | for j in data: 92 | if j == '': 93 | continue 94 | key, val = j.split('=') 95 | key = key.strip() 96 | val = val.strip() 97 | if val.startswith('0x'): 98 | cur_dict[key] = int(val, 16) 99 | else: 100 | cur_dict[key] = int(val) 101 | miss_list.append(cur_dict) 102 | return miss_list 103 | 104 | 105 | def parse_accesses(access_lines): 106 | access_dict = {} 107 | for i in access_lines: 108 | tmp = i.split(':') 109 | key = int(tmp[0], 16) 110 | val = int(tmp[1]) 111 | access_dict[key] = val 112 | return access_dict 113 | 114 | def parse_latency(latency_lines): 115 | latency_dict = {} 116 | 117 | for i in latency_lines: 118 | if i != '': 119 | tmp = i.split(':') 120 | key = tmp[0].strip() 121 | if key.isdigit(): 122 | key = int(key) 123 | val = int(tmp[1].strip()) 124 | latency_dict[key] = val 125 | 126 | return latency_dict 127 | 128 | def parse_sets(set_lines): 129 | set_dict = {} 130 | 131 | for i in set_lines: 132 | if i != '': 133 | tmp = i.split(':') 134 | key = int(tmp[0].strip()) 135 | val = int(tmp[1].strip()) 136 | set_dict[key] = val 137 | 138 | return set_dict 139 | 140 | def parse_log(filename): 141 | sections = parse_file(filename) 142 | 143 | log_data = {} 144 | log_data['total'] = parse_total(sections['total']) 145 | log_data['epoch'] = parse_epoch(sections['epoch']) 146 | log_data['miss'] = parse_misses(sections['miss']) 147 | log_data['access'] = parse_accesses(sections['access']) 148 | log_data['latency'] = parse_latency(sections['latency']) 149 | log_data['sets'] = parse_sets(sections['sets']) 150 | 151 | return log_data 152 | 153 | def parse_logs(file_dict): 154 | log_dict = {} 155 | for i in file_dict: 156 | log_dict[i] = parse_log(file_dict[i]) 157 | return log_dict 158 | 159 | def pretty_print(log_data, d=6): 160 | pp = pprint.PrettyPrinter(depth=d) 161 | pp.pprint(log_data) 162 | 163 | def new_figure(): 164 | global FIGURE_CNT 165 | plt.figure(FIGURE_CNT) 166 | FIGURE_CNT += 1 167 | 168 | 169 | def plot_latency_histogram(log_data, output_file): 170 | # Get the latency data. 171 | latency_dict = log_data['latency'] 172 | 173 | # Number of bins. 174 | N = latency_dict['HISTOGRAM_MAX'] / latency_dict['HISTOGRAM_BIN'] + 1 175 | 176 | # Get the latency histogram values. 177 | vals = [] 178 | for i in range(N): 179 | vals.append(latency_dict[i*latency_dict['HISTOGRAM_BIN']]) 180 | 181 | # Make the plot. 182 | ind = np.arange(N) # the x locations 183 | new_figure() 184 | p1 = plt.bar(ind, vals) 185 | 186 | # Label it. 187 | plt.ylabel('Accesses') 188 | plt.xlabel('Latency (x100)') 189 | plt.title('Histogram of HybridSim Latencies') 190 | 191 | # Save to file. 192 | plt.savefig(output_file) 193 | 194 | def plot_misses(log_data, output_file): 195 | miss_list = log_data['miss'] 196 | x_vals = [] 197 | y_vals = [] 198 | for i in miss_list: 199 | x_vals.append(i['address']) 200 | y_vals.append(i['missed']) 201 | 202 | new_figure() 203 | p1 = plt.scatter(x_vals, y_vals) 204 | 205 | plt.ylabel('Address') 206 | plt.xlabel('Cycle') 207 | plt.title('HybridSim Cache Misses') 208 | 209 | plt.savefig(output_file) 210 | 211 | def plot_epochs(log_data, output_file, a, b): 212 | epoch_list = log_data['epoch'] 213 | 214 | x_vals = [] 215 | y_vals = [] 216 | for i in range(len(epoch_list)): 217 | x_vals.append(i) 218 | y_vals.append(epoch_list[i][a][b]) 219 | 220 | new_figure() 221 | p1 = plt.scatter(x_vals, y_vals) 222 | 223 | y_label = a+' '+b 224 | plt.ylabel(y_label) 225 | plt.xlabel('Epoch') 226 | plt.title('HybridSim '+y_label+' per epoch') 227 | 228 | plt.savefig(output_file) 229 | 230 | 231 | log_dict = parse_logs({1: 'hybridsim.log', 2: 'hybridsim2.log'}) 232 | print log_dict[2] 233 | #log_data = parse_log('hybridsim.log') 234 | 235 | #pretty_print(log_data['miss'], 2) 236 | #pretty_print(log_data, 6) 237 | 238 | #plot_latency_histogram(log_data, 'plots/latency.png') 239 | #plot_misses(log_data, 'plots/misses.png') 240 | #plot_epochs(log_data, 'plots/accesses_per_epoch.png', 'total', 'total accesses') 241 | -------------------------------------------------------------------------------- /IniReader.cpp: -------------------------------------------------------------------------------- 1 | /********************************************************************************* 2 | * Copyright (c) 2010-2011, 3 | * Jim Stevens, Paul Tschirhart, Ishwar Singh Bhati, Mu-Tien Chang, Peter Enns, 4 | * Elliott Cooper-Balis, Paul Rosenfeld, Bruce Jacob 5 | * University of Maryland 6 | * Contact: jims [at] cs [dot] umd [dot] edu 7 | * All rights reserved. 8 | * 9 | * Redistribution and use in source and binary forms, with or without 10 | * modification, are permitted provided that the following conditions are met: 11 | * 12 | * * Redistributions of source code must retain the above copyright notice, 13 | * this list of conditions and the following disclaimer. 14 | * 15 | * * Redistributions in binary form must reproduce the above copyright notice, 16 | * this list of conditions and the following disclaimer in the documentation 17 | * and/or other materials provided with the distribution. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | *********************************************************************************/ 30 | 31 | #include "IniReader.h" 32 | 33 | // Define the globals read from the ini file here. 34 | // Also provide default values here. 35 | 36 | namespace HybridSim 37 | { 38 | 39 | // Other constants 40 | uint64_t CONTROLLER_DELAY = 2; 41 | 42 | uint64_t ENABLE_LOGGER = 1; 43 | uint64_t EPOCH_LENGTH = 200000; 44 | uint64_t HISTOGRAM_BIN = 100; 45 | uint64_t HISTOGRAM_MAX = 20000; 46 | 47 | // these values are also specified in the ini file of the nvdimm but have a different name 48 | uint64_t PAGE_SIZE = 4096; // in bytes, so divide this by 64 to get the number of DDR3 transfers per page 49 | 50 | 51 | 52 | uint64_t SET_SIZE = 64; // associativity of cache 53 | 54 | uint64_t BURST_SIZE = 64; // number of bytes in a single transaction, this means with PAGE_SIZE=1024, 16 transactions are needed 55 | uint64_t FLASH_BURST_SIZE = 4096; // number of bytes in a single flash transaction 56 | 57 | // Number of pages total and number of pages in the cache 58 | uint64_t TOTAL_PAGES = 2097152/4; // 2 GB 59 | uint64_t CACHE_PAGES = 1048576/4; // 1 GB 60 | 61 | 62 | // Defined in marss memoryHierachy.cpp. 63 | // Need to confirm this and make it more flexible later. 64 | uint64_t CYCLES_PER_SECOND = 667000000; 65 | 66 | // INI files 67 | string dram_ini = "ini/DDR3_micron_8M_8B_x8_sg15.ini"; 68 | string flash_ini = "ini/samsung_K9XXG08UXM(mod).ini"; 69 | string sys_ini = "ini/system.ini"; 70 | 71 | // Save/Restore options 72 | uint64_t ENABLE_RESTORE = 0; 73 | uint64_t ENABLE_SAVE = 0; 74 | string HYBRIDSIM_RESTORE_FILE = "none"; 75 | string NVDIMM_RESTORE_FILE = "none"; 76 | string HYBRIDSIM_SAVE_FILE = "none"; 77 | string NVDIMM_SAVE_FILE = "none"; 78 | 79 | 80 | void IniReader::read(string inifile) 81 | { 82 | ifstream inFile; 83 | char tmp[256]; 84 | string tmp2; 85 | list lines; 86 | 87 | inFile.open(inifile); 88 | if (!inFile.is_open()) 89 | { 90 | cerr << "ERROR: Failed to load HybridSim's Ini file: " << inifile << "\n"; 91 | abort(); 92 | } 93 | 94 | while(!inFile.eof()) 95 | { 96 | inFile.getline(tmp, 256); 97 | tmp2 = (string)tmp; 98 | 99 | // Filter comments out. 100 | size_t pos = tmp2.find("#"); 101 | tmp2 = tmp2.substr(0, pos); 102 | 103 | // Strip whitespace from the ends. 104 | tmp2 = strip(tmp2); 105 | 106 | // Filter newlines out. 107 | if (tmp2.empty()) 108 | continue; 109 | 110 | // Add it to the lines list. 111 | lines.push_back(tmp2); 112 | } 113 | inFile.close(); 114 | 115 | list::iterator it; 116 | for (it = lines.begin(); it != lines.end(); it++) 117 | { 118 | list split_line = split((*it), "=", 2); 119 | 120 | if (split_line.size() != 2) 121 | { 122 | cerr << "ERROR: Parsing ini failed on line: " << (*it) << "\n"; 123 | cerr << "There should be exactly one '=' per line\n"; 124 | abort(); 125 | } 126 | 127 | string key = split_line.front(); 128 | string value = split_line.back(); 129 | 130 | // Place the value into the appropriate global. 131 | if (key.compare("CONTROLLER_DELAY") == 0) 132 | convert_uint64_t(CONTROLLER_DELAY, value, key); 133 | else if (key.compare("ENABLE_LOGGER") == 0) 134 | convert_uint64_t(ENABLE_LOGGER, value, key); 135 | else if (key.compare("EPOCH_LENGTH") == 0) 136 | convert_uint64_t(EPOCH_LENGTH, value, key); 137 | else if (key.compare("HISTOGRAM_BIN") == 0) 138 | convert_uint64_t(HISTOGRAM_BIN, value, key); 139 | else if (key.compare("HISTOGRAM_MAX") == 0) 140 | convert_uint64_t(HISTOGRAM_MAX, value, key); 141 | else if (key.compare("PAGE_SIZE") == 0) 142 | convert_uint64_t(PAGE_SIZE, value, key); 143 | else if (key.compare("SET_SIZE") == 0) 144 | convert_uint64_t(SET_SIZE, value, key); 145 | else if (key.compare("BURST_SIZE") == 0) 146 | convert_uint64_t(BURST_SIZE, value, key); 147 | else if (key.compare("FLASH_BURST_SIZE") == 0) 148 | convert_uint64_t(FLASH_BURST_SIZE, value, key); 149 | else if (key.compare("TOTAL_PAGES") == 0) 150 | convert_uint64_t(TOTAL_PAGES, value, key); 151 | else if (key.compare("CACHE_PAGES") == 0) 152 | convert_uint64_t(CACHE_PAGES, value, key); 153 | else if (key.compare("CYCLES_PER_SECOND") == 0) 154 | convert_uint64_t(CYCLES_PER_SECOND, value, key); 155 | else if (key.compare("dram_ini") == 0) 156 | dram_ini = value; 157 | else if (key.compare("flash_ini") == 0) 158 | flash_ini = value; 159 | else if (key.compare("sys_ini") == 0) 160 | sys_ini = value; 161 | else if (key.compare("ENABLE_RESTORE") == 0) 162 | convert_uint64_t(ENABLE_RESTORE, value, key); 163 | else if (key.compare("ENABLE_SAVE") == 0) 164 | convert_uint64_t(ENABLE_SAVE, value, key); 165 | else if (key.compare("HYBRIDSIM_RESTORE_FILE") == 0) 166 | HYBRIDSIM_RESTORE_FILE = value; 167 | else if (key.compare("HYBRIDSIM_SAVE_FILE") == 0) 168 | HYBRIDSIM_SAVE_FILE = value; 169 | else if (key.compare("NVDIMM_RESTORE_FILE") == 0) 170 | NVDIMM_RESTORE_FILE = value; 171 | else if (key.compare("NVDIMM_SAVE_FILE") == 0) 172 | NVDIMM_SAVE_FILE = value; 173 | else 174 | { 175 | cerr << "ERROR: Illegal key/value pair in HybridSim ini file: " << key << "=" << value << "\n"; 176 | cerr << "This could either be due to an illegal key or the incorrect value type for a key\n"; 177 | abort(); 178 | } 179 | } 180 | } 181 | } 182 | -------------------------------------------------------------------------------- /old/TraceBasedSim_paul.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * DRAMSim2: A Cycle Accurate DRAM simulator 3 | * 4 | * Copyright (C) 2010 Elliott Cooper-Balis 5 | * Paul Rosenfeld 6 | * Bruce Jacob 7 | * University of Maryland 8 | * 9 | * This program is free software: you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License as published by 11 | * the Free Software Foundation, either version 3 of the License, or 12 | * (at your option) any later version. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with this program. If not, see . 21 | * 22 | *****************************************************************************/ 23 | 24 | 25 | 26 | #include "TraceBasedSim.h" 27 | 28 | using namespace HybridSim; 29 | using namespace std; 30 | 31 | int complete = 0; 32 | 33 | int main() 34 | { 35 | printf("hybridsim_test main()\n"); 36 | some_object obj; 37 | obj.add_one_and_run(); 38 | } 39 | 40 | 41 | void some_object::read_complete(uint id, uint64_t address, uint64_t clock_cycle) 42 | { 43 | printf("[Callback] read complete: %d 0x%lx cycle=%lu\n", id, address, clock_cycle); 44 | complete++; 45 | } 46 | 47 | void some_object::write_complete(uint id, uint64_t address, uint64_t clock_cycle) 48 | { 49 | printf("[Callback] write complete: %d 0x%lx cycle=%lu\n", id, address, clock_cycle); 50 | complete++; 51 | } 52 | 53 | /* FIXME: this may be broken, currently */ 54 | /*void power_callback(double a, double b, double c, double d) 55 | { 56 | printf("power callback: %0.3f, %0.3f, %0.3f, %0.3f\n",a,b,c,d); 57 | }*/ 58 | 59 | int some_object::add_one_and_run() 60 | { 61 | /* pick a DRAM part to simulate */ 62 | HybridSystem *mem = new HybridSystem(1); 63 | //MemorySystem *mem = new MemorySystem(0, "ini/DDR3_micron_32M_8B_x8_sg15.ini", "ini/system.ini", "", ""); 64 | 65 | 66 | /* create and register our callback functions */ 67 | typedef CallbackBase Callback_t; 68 | Callback_t *read_cb = new Callback(this, &some_object::read_complete); 69 | Callback_t *write_cb = new Callback(this, &some_object::write_complete); 70 | mem->RegisterCallbacks(read_cb, write_cb); 71 | 72 | srand (time(NULL)); 73 | 74 | mem->addTransaction(false, 140708070030063); 75 | for (uint64_t i=0; i<10000; i++) 76 | { 77 | mem->update(); 78 | } 79 | 80 | 81 | cout << "Preparing transactions to preload cache with data...\n"; 82 | //uint64_t num_init = 10000; 83 | /*for (uint64_t i=0; iaddTransaction(t); 88 | if (i%10000 == 0) 89 | cout << i << "/" << num_init << endl; 90 | } 91 | 92 | cout << "Running transactions to preload cache with data...\n"; 93 | int factor = 10; 94 | for (uint64_t i=0; iupdate(); 97 | if (i%1000000 == 0) 98 | { 99 | cout << i << "/" << num_init*factor << endl; 100 | } 101 | }*/ 102 | 103 | uint64_t cur_addr = 0; 104 | 105 | //const uint64_t NUM_ACCESSES = 100; 106 | //const int MISS_RATE = 10; 107 | 108 | cout << "Number of sets is" << NUM_SETS << endl; 109 | cout << "Starting flash test...\n"; 110 | cout << "triggering writebacks to flash..." << endl; 111 | for (uint64_t i=0; i<64; i++) 112 | { 113 | TransactionType type = DATA_WRITE; 114 | 115 | cur_addr = (i*4096)*4096; //set size 64 so mod 64 should fill only one set 116 | 117 | DRAMSim::Transaction t = DRAMSim::Transaction(type, cur_addr, NULL); 118 | mem->addTransaction(t); 119 | 120 | #if DEBUG_CACHE 121 | cout << "\n\tAdded transaction " << i << " of type=" << type << " addr=" << cur_addr << " set=" << SET_INDEX(cur_addr) 122 | << " tag=" << TAG(cur_addr) << endl; 123 | #endif 124 | 125 | // TODO: not sure this update factor is correct for this test 126 | for (int j=0; j<10000; j++) 127 | { 128 | mem->update(); 129 | } 130 | } 131 | 132 | // the misses 133 | cur_addr = 262144; 134 | for (uint64_t i=0; i<36; i++) 135 | { 136 | TransactionType type = DATA_WRITE; 137 | 138 | cur_addr = 1073741824+((i*4096)*4096); //set size 64 so mod 64 should fill only one set 139 | 140 | DRAMSim::Transaction t = DRAMSim::Transaction(type, cur_addr, NULL); 141 | mem->addTransaction(t); 142 | 143 | #if DEBUG_CACHE 144 | cout << "\n\tAdded transaction " << i << " of type=" << type << " addr=" << cur_addr << " set=" << SET_INDEX(cur_addr) 145 | << " tag=" << TAG(cur_addr) << endl; 146 | #endif 147 | 148 | // TODO: not sure this update factor is correct for this test 149 | for (int j=0; j<10000; j++) 150 | { 151 | mem->update(); 152 | } 153 | } 154 | 155 | cur_addr = 0; 156 | 157 | cout << "reading from flash... hopefully" << endl; 158 | for (uint64_t i=0; i<1000; i++) 159 | { 160 | TransactionType type = DATA_READ; 161 | 162 | cur_addr = (i*4096)*4096; //set size 64 so mod 64 should fill only one set 163 | 164 | DRAMSim::Transaction t = DRAMSim::Transaction(type, cur_addr, NULL); 165 | mem->addTransaction(t); 166 | 167 | #if DEBUG_CACHE 168 | cout << "\n\tAdded transaction " << i << " of type=" << type << " addr=" << cur_addr << " set=" << SET_INDEX(cur_addr) 169 | << " tag=" << TAG(cur_addr) << endl; 170 | #endif 171 | 172 | // TODO: not sure this update factor is correct for this test 173 | for (int j=0; j<10000; j++) 174 | { 175 | mem->update(); 176 | } 177 | } 178 | 179 | for (int i=0; i<50000000; i++) 180 | { 181 | mem->update(); 182 | } 183 | 184 | 185 | cout << "\n\n" << mem->currentClockCycle << ": completed " << complete << "\n\n"; 186 | cout << "dram_pending=" << mem->dram_pending.size() << " flash_pending=" << mem->flash_pending.size() << "\n\n"; 187 | cout << "dram_queue=" << mem->dram_queue.size() << " flash_queue=" << mem->flash_queue.size() << "\n\n"; 188 | cout << "pending_pages=" << mem->pending_pages.size() << "\n\n"; 189 | for (set::iterator it = mem->pending_pages.begin(); it != mem->pending_pages.end(); it++) 190 | { 191 | cout << (*it) << " "; 192 | } 193 | cout << "\n\n"; 194 | cout << "pending_count=" << mem->pending_count << "\n\n"; 195 | cout << "dram_pending_set.size() =" << mem->dram_pending_set.size() << "\n\n"; 196 | cout << "dram_bad_address.size() = " << mem->dram_bad_address.size() << "\n"; 197 | for (list::iterator it = mem->dram_bad_address.begin(); it != mem->dram_bad_address.end(); it++) 198 | { 199 | cout << (*it) << " "; 200 | } 201 | cout << "\n\n"; 202 | cout << "pending_sets.size() = " << mem->pending_sets.size() << "\n\n"; 203 | cout << "pending_sets_max = " << mem->pending_sets_max << "\n\n"; 204 | cout << "pending_pages_max = " << mem->pending_pages_max << "\n\n"; 205 | cout << "trans_queue_max = " << mem->trans_queue_max << "\n\n"; 206 | 207 | mem->saveStats(); 208 | //mem->flash->printStats(); 209 | mem->reportPower(); 210 | 211 | mem->printLogfile(); 212 | 213 | for (int i=0; i<500; i++) 214 | { 215 | mem->update(); 216 | } 217 | 218 | return 0; 219 | } 220 | 221 | -------------------------------------------------------------------------------- /tools/extract/merge_dict.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import pprint 3 | pp = pprint.PrettyPrinter(indent=4) 4 | 5 | POINTS = 3 6 | 7 | if len(sys.argv) < 4: 8 | sys.stderr.write('Usage: '+sys.argv[0]+' mode inputfile1 inputfile2 ...\n') 9 | sys.stderr.write('Valid modes are: latency, prefetching, channel, buffering\n') 10 | sys.stderr.write('Need at least two input files.\n') 11 | sys.exit(1) 12 | 13 | dict_list = [] 14 | dict_names = [] 15 | 16 | # Check the mode 17 | mode = sys.argv[1] 18 | valid_modes = ['latency', 'prefetching', 'channel', 'buffering'] 19 | if mode not in valid_modes: 20 | sys.stderr.write('Mode '+mode+' is invalid.\n') 21 | sys.stderr.write('Valid modes are: '+str(valid_modes)+'\n') 22 | sys.exit(1) 23 | 24 | # Load the dictionries from file 25 | for i in sys.argv[2:]: 26 | inFile = open(i, 'r') 27 | instr = inFile.read() 28 | inFile.close() 29 | try: 30 | indict = eval(instr) 31 | except: 32 | sys.stderr.write(i+' did not work with the eval() function.\n') 33 | sys.exit(1) 34 | if not type(indict) == type({}): 35 | sys.stderr.write(i+' did not generate a dictionary data structure.\n') 36 | sys.exit(1) 37 | dict_list.append(indict) 38 | dict_names.append(i) 39 | 40 | print 'Parsed the following dictionaries:' 41 | print dict_names 42 | 43 | 44 | # Merge the dictionaries. 45 | num_runs = 0 46 | num_good = 0 47 | master = {} 48 | 49 | if mode == 'latency': 50 | for i in range(len(dict_list)): 51 | cur = dict_list[i] 52 | curname = dict_names[i] 53 | for benchmark in cur: 54 | if benchmark not in master: 55 | master[benchmark] = {} 56 | for latency in cur[benchmark]: 57 | sim_types = ['Hybrid', 'SSD'] 58 | if latency not in master[benchmark]: 59 | master[benchmark][latency] = {} 60 | for sim_type in sim_types: 61 | master[benchmark][latency][sim_type] = [] 62 | for sim_type in sim_types: 63 | if sim_type not in cur[benchmark][latency]: 64 | sys.stderr.write(sim_type+' not found in '+curname+'['+benchmark+']['+latency+']\n') 65 | sys.exit(1) 66 | master[benchmark][latency][sim_type].extend(cur[benchmark][latency][sim_type]) 67 | num_runs += len(cur[benchmark][latency][sim_type]) 68 | num_good += len([i for i in cur[benchmark][latency][sim_type] if i != 0.0]) 69 | 70 | elif mode == 'prefetching': 71 | for i in range(len(dict_list)): 72 | cur = dict_list[i] 73 | curname = dict_names[i] 74 | for benchmark in cur: 75 | if benchmark not in master: 76 | master[benchmark] = {} 77 | for latency in cur[benchmark]: 78 | if latency not in master[benchmark]: 79 | master[benchmark][latency] = {} 80 | for window in cur[benchmark][latency]: 81 | if window not in master[benchmark][latency]: 82 | master[benchmark][latency][window] = [] 83 | master[benchmark][latency][window].extend(cur[benchmark][latency][window]) 84 | num_runs += len(cur[benchmark][latency][window]) 85 | num_good += len([i for i in cur[benchmark][latency][window] if i != 0.0]) 86 | 87 | 88 | elif mode == 'channel': 89 | for i in range(len(dict_list)): 90 | cur = dict_list[i] 91 | curname = dict_names[i] 92 | for benchmark in cur: 93 | if benchmark not in master: 94 | master[benchmark] = {} 95 | for channels in cur[benchmark]: 96 | if channels not in master[benchmark]: 97 | master[benchmark][channels] = {} 98 | for dies in cur[benchmark][channels]: 99 | sim_types = ['Hybrid', 'SSD'] 100 | if dies not in master[benchmark][channels]: 101 | master[benchmark][channels][dies] = {} 102 | for sim_type in sim_types: 103 | master[benchmark][channels][dies][sim_type] = [] 104 | for sim_type in sim_types: 105 | if sim_type not in cur[benchmark][channels][dies]: 106 | sys.stderr.write(sim_type+' not found in '+curname+'['+benchmark+']['+channels+']['+dies+']\n') 107 | sys.exit(1) 108 | master[benchmark][channels][dies][sim_type].extend(cur[benchmark][channels][dies][sim_type]) 109 | num_runs += len(cur[benchmark][channels][dies][sim_type]) 110 | num_good += len([i for i in cur[benchmark][channels][dies][sim_type] if i != 0.0]) 111 | 112 | elif mode == 'buffering': 113 | for i in range(len(dict_list)): 114 | cur = dict_list[i] 115 | curname = dict_names[i] 116 | for benchmark in cur: 117 | if benchmark not in master: 118 | master[benchmark] = {} 119 | for channels in cur[benchmark]: 120 | if channels not in master[benchmark]: 121 | master[benchmark][channels] = [] 122 | master[benchmark][channels].extend(cur[benchmark][channels]) 123 | num_runs += len(cur[benchmark][channels]) 124 | num_good += len([i for i in cur[benchmark][channels] if i != 0.0]) 125 | 126 | 127 | def int_sorted(str_list): 128 | num_list = [int(i) for i in str_list] 129 | num_list.sort() 130 | return [str(i) for i in num_list] 131 | def float_sorted(str_list): 132 | num_list = [float(i) for i in str_list] 133 | num_list.sort() 134 | return [str(i) for i in num_list] 135 | 136 | #pp.pprint(master) 137 | print 'Total runs:',num_runs 138 | print 'Good runs:',num_good 139 | 140 | table_list = [] 141 | 142 | # Generate the table format 143 | 144 | if mode == 'latency': 145 | for benchmark in sorted(master.keys()): 146 | for latency in int_sorted(master[benchmark].keys()): 147 | new_entry = benchmark+'\t'+latency+'\t' 148 | sim_types = ['Hybrid', 'SSD'] 149 | for sim_type in sim_types: 150 | count = 0 151 | for ipc in master[benchmark][latency][sim_type]: 152 | if ipc != 0.0: 153 | new_entry += str(ipc) +'\t' 154 | count += 1 155 | if count == POINTS: 156 | break 157 | while count < POINTS: 158 | new_entry += str(0.0) + '\t' 159 | count += 1 160 | table_list.append(new_entry) 161 | 162 | elif mode == 'prefetching': 163 | for benchmark in master: 164 | for latency in int_sorted(master[benchmark].keys()): 165 | for window in int_sorted(master[benchmark][latency].keys()): 166 | new_entry = benchmark+'\t'+latency+'\t'+window+'\t' 167 | count = 0 168 | for ipc in master[benchmark][latency][window]: 169 | if ipc != 0.0: 170 | new_entry += str(ipc) +'\t' 171 | count += 1 172 | if count == POINTS: 173 | break 174 | while count < POINTS: 175 | new_entry += str(0.0) + '\t' 176 | count += 1 177 | table_list.append(new_entry) 178 | 179 | 180 | elif mode == 'channel': 181 | for benchmark in master: 182 | for channels in int_sorted(master[benchmark].keys()): 183 | for dies in int_sorted(master[benchmark][channels].keys()): 184 | sim_types = ['Hybrid', 'SSD'] 185 | new_entry = benchmark+'\t'+channels+'\t'+dies+'\t' 186 | for sim_type in sim_types: 187 | count = 0 188 | for ipc in master[benchmark][channels][dies][sim_type]: 189 | if ipc != 0.0: 190 | new_entry += str(ipc) +'\t' 191 | count += 1 192 | if count == POINTS: 193 | break 194 | while count < POINTS: 195 | new_entry += str(0.0) + '\t' 196 | count += 1 197 | table_list.append(new_entry) 198 | 199 | 200 | 201 | elif mode == 'buffering': 202 | for benchmark in master: 203 | for channels in int_sorted(master[benchmark].keys()): 204 | new_entry = benchmark+'\t'+channels+'\t' 205 | count = 0 206 | for ipc in master[benchmark][channels]: 207 | if ipc != 0.0: 208 | new_entry += str(ipc) +'\t' 209 | count += 1 210 | if count == POINTS: 211 | break 212 | while count < POINTS: 213 | new_entry += str(0.0) + '\t' 214 | count += 1 215 | table_list.append(new_entry) 216 | 217 | print 'table:' 218 | for i in table_list: 219 | print i 220 | -------------------------------------------------------------------------------- /traces/3_seq_page.txt: -------------------------------------------------------------------------------- 1 | 0 0 536870912 2 | 100 0 1610612736 3 | 200 0 2684354560 4 | 300 0 536875008 5 | 400 0 1610616832 6 | 500 0 2684358656 7 | 600 0 536879104 8 | 700 0 1610620928 9 | 800 0 2684362752 10 | 900 0 536883200 11 | 1000 0 1610625024 12 | 1100 0 2684366848 13 | 1200 0 536887296 14 | 1300 0 1610629120 15 | 1400 0 2684370944 16 | 1500 0 536891392 17 | 1600 0 1610633216 18 | 1700 0 2684375040 19 | 1800 0 536895488 20 | 1900 0 1610637312 21 | 2000 0 2684379136 22 | 2100 0 536899584 23 | 2200 0 1610641408 24 | 2300 0 2684383232 25 | 2400 0 536903680 26 | 2500 0 1610645504 27 | 2600 0 2684387328 28 | 2700 0 536907776 29 | 2800 0 1610649600 30 | 2900 0 2684391424 31 | 3000 0 536911872 32 | 3100 0 1610653696 33 | 3200 0 2684395520 34 | 3300 0 536915968 35 | 3400 0 1610657792 36 | 3500 0 2684399616 37 | 3600 0 536920064 38 | 3700 0 1610661888 39 | 3800 0 2684403712 40 | 3900 0 536924160 41 | 4000 0 1610665984 42 | 4100 0 2684407808 43 | 4200 0 536928256 44 | 4300 0 1610670080 45 | 4400 0 2684411904 46 | 4500 0 536932352 47 | 4600 0 1610674176 48 | 4700 0 2684416000 49 | 4800 0 536936448 50 | 4900 0 1610678272 51 | 5000 0 2684420096 52 | 5100 0 536940544 53 | 5200 0 1610682368 54 | 5300 0 2684424192 55 | 5400 0 536944640 56 | 5500 0 1610686464 57 | 5600 0 2684428288 58 | 5700 0 536948736 59 | 5800 0 1610690560 60 | 5900 0 2684432384 61 | 6000 0 536952832 62 | 6100 0 1610694656 63 | 6200 0 2684436480 64 | 6300 0 536956928 65 | 6400 0 1610698752 66 | 6500 0 2684440576 67 | 6600 0 536961024 68 | 6700 0 1610702848 69 | 6800 0 2684444672 70 | 6900 0 536965120 71 | 7000 0 1610706944 72 | 7100 0 2684448768 73 | 7200 0 536969216 74 | 7300 0 1610711040 75 | 7400 0 2684452864 76 | 7500 0 536973312 77 | 7600 0 1610715136 78 | 7700 0 2684456960 79 | 7800 0 536977408 80 | 7900 0 1610719232 81 | 8000 0 2684461056 82 | 8100 0 536981504 83 | 8200 0 1610723328 84 | 8300 0 2684465152 85 | 8400 0 536985600 86 | 8500 0 1610727424 87 | 8600 0 2684469248 88 | 8700 0 536989696 89 | 8800 0 1610731520 90 | 8900 0 2684473344 91 | 9000 0 536993792 92 | 9100 0 1610735616 93 | 9200 0 2684477440 94 | 9300 0 536997888 95 | 9400 0 1610739712 96 | 9500 0 2684481536 97 | 9600 0 537001984 98 | 9700 0 1610743808 99 | 9800 0 2684485632 100 | 9900 0 537006080 101 | 10000 0 1610747904 102 | 10100 0 2684489728 103 | 10200 0 537010176 104 | 10300 0 1610752000 105 | 10400 0 2684493824 106 | 10500 0 537014272 107 | 10600 0 1610756096 108 | 10700 0 2684497920 109 | 10800 0 537018368 110 | 10900 0 1610760192 111 | 11000 0 2684502016 112 | 11100 0 537022464 113 | 11200 0 1610764288 114 | 11300 0 2684506112 115 | 11400 0 537026560 116 | 11500 0 1610768384 117 | 11600 0 2684510208 118 | 11700 0 537030656 119 | 11800 0 1610772480 120 | 11900 0 2684514304 121 | 12000 0 537034752 122 | 12100 0 1610776576 123 | 12200 0 2684518400 124 | 12300 0 537038848 125 | 12400 0 1610780672 126 | 12500 0 2684522496 127 | 12600 0 537042944 128 | 12700 0 1610784768 129 | 12800 0 2684526592 130 | 12900 0 537047040 131 | 13000 0 1610788864 132 | 13100 0 2684530688 133 | 13200 0 537051136 134 | 13300 0 1610792960 135 | 13400 0 2684534784 136 | 13500 0 537055232 137 | 13600 0 1610797056 138 | 13700 0 2684538880 139 | 13800 0 537059328 140 | 13900 0 1610801152 141 | 14000 0 2684542976 142 | 14100 0 537063424 143 | 14200 0 1610805248 144 | 14300 0 2684547072 145 | 14400 0 537067520 146 | 14500 0 1610809344 147 | 14600 0 2684551168 148 | 14700 0 537071616 149 | 14800 0 1610813440 150 | 14900 0 2684555264 151 | 15000 0 537075712 152 | 15100 0 1610817536 153 | 15200 0 2684559360 154 | 15300 0 537079808 155 | 15400 0 1610821632 156 | 15500 0 2684563456 157 | 15600 0 537083904 158 | 15700 0 1610825728 159 | 15800 0 2684567552 160 | 15900 0 537088000 161 | 16000 0 1610829824 162 | 16100 0 2684571648 163 | 16200 0 537092096 164 | 16300 0 1610833920 165 | 16400 0 2684575744 166 | 16500 0 537096192 167 | 16600 0 1610838016 168 | 16700 0 2684579840 169 | 16800 0 537100288 170 | 16900 0 1610842112 171 | 17000 0 2684583936 172 | 17100 0 537104384 173 | 17200 0 1610846208 174 | 17300 0 2684588032 175 | 17400 0 537108480 176 | 17500 0 1610850304 177 | 17600 0 2684592128 178 | 17700 0 537112576 179 | 17800 0 1610854400 180 | 17900 0 2684596224 181 | 18000 0 537116672 182 | 18100 0 1610858496 183 | 18200 0 2684600320 184 | 18300 0 537120768 185 | 18400 0 1610862592 186 | 18500 0 2684604416 187 | 18600 0 537124864 188 | 18700 0 1610866688 189 | 18800 0 2684608512 190 | 18900 0 537128960 191 | 19000 0 1610870784 192 | 19100 0 2684612608 193 | 19200 0 537133056 194 | 19300 0 1610874880 195 | 19400 0 2684616704 196 | 19500 0 537137152 197 | 19600 0 1610878976 198 | 19700 0 2684620800 199 | 19800 0 537141248 200 | 19900 0 1610883072 201 | 20000 0 2684624896 202 | 20100 0 537145344 203 | 20200 0 1610887168 204 | 20300 0 2684628992 205 | 20400 0 537149440 206 | 20500 0 1610891264 207 | 20600 0 2684633088 208 | 20700 0 537153536 209 | 20800 0 1610895360 210 | 20900 0 2684637184 211 | 21000 0 537157632 212 | 21100 0 1610899456 213 | 21200 0 2684641280 214 | 21300 0 537161728 215 | 21400 0 1610903552 216 | 21500 0 2684645376 217 | 21600 0 537165824 218 | 21700 0 1610907648 219 | 21800 0 2684649472 220 | 21900 0 537169920 221 | 22000 0 1610911744 222 | 22100 0 2684653568 223 | 22200 0 537174016 224 | 22300 0 1610915840 225 | 22400 0 2684657664 226 | 22500 0 537178112 227 | 22600 0 1610919936 228 | 22700 0 2684661760 229 | 22800 0 537182208 230 | 22900 0 1610924032 231 | 23000 0 2684665856 232 | 23100 0 537186304 233 | 23200 0 1610928128 234 | 23300 0 2684669952 235 | 23400 0 537190400 236 | 23500 0 1610932224 237 | 23600 0 2684674048 238 | 23700 0 537194496 239 | 23800 0 1610936320 240 | 23900 0 2684678144 241 | 24000 0 537198592 242 | 24100 0 1610940416 243 | 24200 0 2684682240 244 | 24300 0 537202688 245 | 24400 0 1610944512 246 | 24500 0 2684686336 247 | 24600 0 537206784 248 | 24700 0 1610948608 249 | 24800 0 2684690432 250 | 24900 0 537210880 251 | 25000 0 1610952704 252 | 25100 0 2684694528 253 | 25200 0 537214976 254 | 25300 0 1610956800 255 | 25400 0 2684698624 256 | 25500 0 537219072 257 | 25600 0 1610960896 258 | 25700 0 2684702720 259 | 25800 0 537223168 260 | 25900 0 1610964992 261 | 26000 0 2684706816 262 | 26100 0 537227264 263 | 26200 0 1610969088 264 | 26300 0 2684710912 265 | 26400 0 537231360 266 | 26500 0 1610973184 267 | 26600 0 2684715008 268 | 26700 0 537235456 269 | 26800 0 1610977280 270 | 26900 0 2684719104 271 | 27000 0 537239552 272 | 27100 0 1610981376 273 | 27200 0 2684723200 274 | 27300 0 537243648 275 | 27400 0 1610985472 276 | 27500 0 2684727296 277 | 27600 0 537247744 278 | 27700 0 1610989568 279 | 27800 0 2684731392 280 | 27900 0 537251840 281 | 28000 0 1610993664 282 | 28100 0 2684735488 283 | 28200 0 537255936 284 | 28300 0 1610997760 285 | 28400 0 2684739584 286 | 28500 0 537260032 287 | 28600 0 1611001856 288 | 28700 0 2684743680 289 | 28800 0 537264128 290 | 28900 0 1611005952 291 | 29000 0 2684747776 292 | 29100 0 537268224 293 | 29200 0 1611010048 294 | 29300 0 2684751872 295 | 29400 0 537272320 296 | 29500 0 1611014144 297 | 29600 0 2684755968 298 | 29700 0 537276416 299 | 29800 0 1611018240 300 | 29900 0 2684760064 301 | -------------------------------------------------------------------------------- /tools/sweep_scripts/ini/TraceBasedSim.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * HybridSim: Simulator for hybrid main memories 3 | * 4 | * Copyright (C) 2010 Jim Stevens 5 | * Peter Enns 6 | * Paul Tschirhart 7 | * Ishwar Bhati 8 | * Mutien Chang 9 | * Bruce Jacob 10 | * University of Maryland 11 | * 12 | * This program is free software: you can redistribute it and/or modify 13 | * it under the terms of the GNU General Public License as published by 14 | * the Free Software Foundation, either version 3 of the License, or 15 | * (at your option) any later version. 16 | * 17 | * This program is distributed in the hope that it will be useful, 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | * GNU General Public License for more details. 21 | * 22 | * You should have received a copy of the GNU General Public License 23 | * along with this program. If not, see . 24 | * 25 | *****************************************************************************/ 26 | 27 | 28 | 29 | #include "TraceBasedSim.h" 30 | 31 | using namespace HybridSim; 32 | using namespace std; 33 | 34 | const uint64_t MAX_PENDING = 3000; 35 | //const uint64_t MAX_PENDING = 1000000000; 36 | const uint64_t MIN_PENDING = 2500; 37 | uint64_t complete = 0; 38 | uint64_t pending = 0; 39 | uint64_t throttle_count = 0; 40 | 41 | // The cycle counter is used to keep track of what cycle we are on. 42 | uint64_t cycle_counter = 0; 43 | 44 | uint64_t last_clock = 0; 45 | uint64_t CLOCK_DELAY = 1000000; 46 | 47 | 48 | int main(int argc, char *argv[]) 49 | { 50 | printf("hybridsim_test main()\n"); 51 | HybridSimTBS obj; 52 | 53 | string tracefile = "traces/test.txt"; 54 | if (argc > 1) 55 | { 56 | tracefile = argv[1]; 57 | cout << "Using trace file " << tracefile << "\n"; 58 | } 59 | else 60 | cout << "Using default trace file (traces/test.txt)\n"; 61 | 62 | obj.run_trace(tracefile); 63 | } 64 | 65 | void transaction_complete(uint64_t clock_cycle) 66 | { 67 | complete++; 68 | pending--; 69 | 70 | if ((complete % 10000 == 0) || (clock_cycle - last_clock > CLOCK_DELAY)) 71 | { 72 | cout << "complete= " << complete << "\t\tpending= " << pending << "\t\t cycle_count= "<< clock_cycle << "\t\tthrottle_count=" << throttle_count << "\n"; 73 | last_clock = clock_cycle; 74 | } 75 | 76 | //if (complete == 10000000) 77 | // abort(); 78 | } 79 | 80 | void HybridSimTBS::read_complete(uint id, uint64_t address, uint64_t clock_cycle) 81 | { 82 | //printf("[Callback] read complete: %d 0x%lx cycle=%lu\n", id, address, clock_cycle); 83 | //complete++; 84 | //pending--; 85 | 86 | transaction_complete(clock_cycle); 87 | } 88 | 89 | void HybridSimTBS::write_complete(uint id, uint64_t address, uint64_t clock_cycle) 90 | { 91 | //printf("[Callback] write complete: %d 0x%lx cycle=%lu\n", id, address, clock_cycle); 92 | //complete++; 93 | //pending--; 94 | 95 | transaction_complete(clock_cycle); 96 | } 97 | 98 | int HybridSimTBS::run_trace(string tracefile) 99 | { 100 | HybridSystem *mem = new HybridSystem(1); 101 | 102 | 103 | /* create and register our callback functions */ 104 | typedef CallbackBase Callback_t; 105 | Callback_t *read_cb = new Callback(this, &HybridSimTBS::read_complete); 106 | Callback_t *write_cb = new Callback(this, &HybridSimTBS::write_complete); 107 | mem->RegisterCallbacks(read_cb, write_cb); 108 | 109 | // Open input file 110 | ifstream inFile; 111 | inFile.open(tracefile, ifstream::in); 112 | if (!inFile.is_open()) 113 | { 114 | cout << "ERROR: Failed to load tracefile: " << tracefile << "\n"; 115 | abort(); 116 | } 117 | 118 | 119 | char char_line[256]; 120 | string line; 121 | 122 | while (inFile.good()) 123 | { 124 | // Read the next line. 125 | inFile.getline(char_line, 256); 126 | line = (string)char_line; 127 | 128 | // Filter comments out. 129 | size_t pos = line.find("#"); 130 | line = line.substr(0, pos); 131 | 132 | // Strip whitespace from the ends. 133 | line = strip(line); 134 | 135 | // Filter newlines out. 136 | if (line.empty()) 137 | continue; 138 | 139 | // Split and parse. 140 | list split_line = split(line); 141 | 142 | if (split_line.size() != 3) 143 | { 144 | cout << "ERROR: Parsing trace failed on line:\n" << line << "\n"; 145 | cout << "There should be exactly three numbers per line\n"; 146 | cout << "There are " << split_line.size() << endl; 147 | abort(); 148 | } 149 | 150 | uint64_t line_vals[3]; 151 | 152 | int i = 0; 153 | for (list::iterator it = split_line.begin(); it != split_line.end(); it++, i++) 154 | { 155 | // convert string to integer 156 | uint64_t tmp; 157 | convert_uint64_t(tmp, (*it)); 158 | line_vals[i] = tmp; 159 | } 160 | 161 | // Finish parsing. 162 | uint64_t trans_cycle = line_vals[0]; 163 | bool write = line_vals[1] % 2; 164 | uint64_t addr = line_vals[2]; 165 | 166 | // increment the counter until >= the clock cycle of cur transaction 167 | // for each cycle, call the update() function. 168 | while (cycle_counter < trans_cycle) 169 | { 170 | mem->update(); 171 | cycle_counter++; 172 | } 173 | 174 | // add the transaction and continue 175 | mem->addTransaction(write, addr); 176 | pending++; 177 | 178 | // If the pending count goes above MAX_PENDING, wait until it goes back below MIN_PENDING before adding more 179 | // transactions. This throttling will prevent the memory system from getting overloaded. 180 | if (pending >= MAX_PENDING) 181 | { 182 | //cout << "MAX_PENDING REACHED! Throttling the trace until pending is back below MIN_PENDING.\t\tcycle= " << cycle_counter << "\n"; 183 | throttle_count++; 184 | while (pending > MIN_PENDING) 185 | { 186 | mem->update(); 187 | cycle_counter++; 188 | } 189 | //cout << "Back to MIN_PENDING. Allowing transactions to be added again.\t\tcycle= " << cycle_counter << "\n"; 190 | } 191 | 192 | } 193 | 194 | inFile.close(); 195 | 196 | // Run update until all transactions come back. 197 | while (pending > 0) 198 | { 199 | mem->update(); 200 | cycle_counter++; 201 | } 202 | 203 | // This is a hack for the moment to ensure that a final write completes. 204 | // In the future, we need two callbacks to fix this. 205 | for (int i=0; i<1000000; i++) 206 | mem->update(); 207 | 208 | 209 | cout << "\n\n" << mem->currentClockCycle << ": completed " << complete << "\n\n"; 210 | cout << "dram_pending=" << mem->dram_pending.size() << " flash_pending=" << mem->flash_pending.size() << "\n\n"; 211 | cout << "dram_queue=" << mem->dram_queue.size() << " flash_queue=" << mem->flash_queue.size() << "\n\n"; 212 | cout << "pending_pages=" << mem->pending_pages.size() << "\n\n"; 213 | for (set::iterator it = mem->pending_pages.begin(); it != mem->pending_pages.end(); it++) 214 | { 215 | cout << (*it) << " "; 216 | } 217 | cout << "\n\n"; 218 | cout << "pending_count=" << mem->pending_count << "\n\n"; 219 | cout << "dram_pending_set.size() =" << mem->dram_pending_set.size() << "\n\n"; 220 | cout << "dram_bad_address.size() = " << mem->dram_bad_address.size() << "\n"; 221 | for (list::iterator it = mem->dram_bad_address.begin(); it != mem->dram_bad_address.end(); it++) 222 | { 223 | cout << (*it) << " "; 224 | } 225 | cout << "\n\n"; 226 | cout << "pending_sets.size() = " << mem->pending_sets.size() << "\n\n"; 227 | cout << "pending_sets_max = " << mem->pending_sets_max << "\n\n"; 228 | cout << "pending_pages_max = " << mem->pending_pages_max << "\n\n"; 229 | cout << "trans_queue_max = " << mem->trans_queue_max << "\n\n"; 230 | 231 | mem->printLogfile(); 232 | 233 | for (int i=0; i<500; i++) 234 | { 235 | mem->update(); 236 | } 237 | 238 | return 0; 239 | } 240 | 241 | --------------------------------------------------------------------------------