CACTI — Cache Area, Timing & Power Modeling
Analytical model for SRAM/DRAM/CAM access time, cycle time, area, and power
CACTI (HP Labs) exhaustively searches the cache partition design space—varying word-line divisions, bit-line divisions, mux degrees, and wire types—to find Pareto-optimal configurations for any given cache geometry and technology node.
📚 What is CACTI & why does it exist?
CACTI answers the fundamental question: “If I build a cache with these dimensions, how fast, how big, and how power-hungry will it be?” Given parameters like cache size, block size, associativity, and technology node, CACTI explores millions of internal partitioning options and returns the access time, cycle time, die area, dynamic power, and leakage power of the optimal design. AccelWattch calls into CACTI every time it needs to model a GPU cache, register file, TLB, or any on-chip SRAM/CAM array.
💡 Real-world analogy
Think of CACTI as an architect’s cost estimator for buildings. When a client says “I want a 50-story office tower with 200 rooms per floor,” the estimator doesn’t just guess—they evaluate different floor plans, structural beam arrangements, elevator placements, and HVAC layouts. Each combination yields different costs (price), construction time (delay), and floor area (chip area). CACTI does exactly this for caches: it tries every combination of row/column partitions, wiring strategies, and decoder topologies, then picks the design that best balances speed, area, and power. The “building materials” are transistors and wires at a specific technology node (e.g., 22 nm).
Contents
Architecture
CACTI models a cache as a hierarchy of components. The top-level solver (Ucache) partitions the array and delegates to UCA/Nuca, which compose banks, mats, subarrays, decoders, and H-tree routing networks.
classDiagram
class Component {
+Area area
+powerDef power
+double delay
+double cycle_time
}
class UCA {
+Bank bank
+Htree2* htree_in_add
+Htree2* htree_in_data
+Htree2* htree_out_data
+compute_delays()
+compute_power_energy()
}
class Bank {
+Mat mat
+Htree2* htree_in_add
+int num_mats_hor_dir
+compute_delays()
}
class Mat {
+Subarray subarray
+Decoder* row_dec
+Predec* r_predec
+Wire* subarray_out_wire
+compute_delays()
+compute_bitline_delay()
+compute_sa_delay()
}
class Subarray {
+uint num_rows
+uint num_cols
+double C_wl, R_wl, C_bl
+get_total_cell_area()
}
class Wire {
+Wire_type wt
+double repeater_size
+double repeater_spacing
+calculate_wire_stats()
+delay_optimal_wire()
+wire_cap()
+wire_res()
}
class Decoder {
+int num_in_signals
+int num_gates
+compute_widths()
+compute_delays()
}
class Htree2 {
+Htree_type tree_type
+int add_bits, data_in_bits
+in_htree()
+out_htree()
}
class Crossbar {
+double n_inp, n_out
+double flit_size
+compute_power()
}
class MCPAT_Router {
+Component arbiter
+Component crossbar
+Component buffer
+calc_router_parameters()
}
Component <|-- UCA
Component <|-- Bank
Component <|-- Mat
Component <|-- Subarray
Component <|-- Wire
Component <|-- Decoder
Component <|-- Htree2
Component <|-- Crossbar
Component <|-- MCPAT_Router
UCA *-- Bank
UCA *-- Htree2
Bank *-- Mat
Bank *-- Htree2
Mat *-- Subarray
Mat *-- Decoder
Mat *-- Wire
MCPAT_Router *-- Crossbar
Data Flow — Cache Parameter Search
When AccelWattch needs power/area/timing for a cache structure, it calls cacti_interface() which triggers an exhaustive multi-threaded search over the partition space.
sequenceDiagram
participant AW as AccelWattch (ArrayST)
participant CI as cacti_interface()
participant UC as Ucache::solve()
participant CT as calculate_time()
participant MT as Mat
participant SA as Subarray
participant WR as Wire
participant UCA as UCA (assemble)
AW->>CI: cacti_interface(InputParameter)
CI->>CI: init_tech_params(F_sz_nm)
CI->>UC: solve(&fin_res)
UC->>UC: spawn N threads
loop For each (Ndwl, Ndbl, Nspd, Ndcm, Ndsam) partition
UC->>CT: calculate_time(is_tag, partition_params)
CT->>SA: Subarray(rows, cols, cell)
SA-->>CT: cell area, C_wl, C_bl
CT->>MT: Mat(subarray, decoders, wire)
MT->>MT: compute_bitline_delay()
MT->>MT: compute_sa_delay()
MT->>WR: Wire(type, length)
WR-->>MT: wire delay, wire power
MT-->>CT: mat delay, mat power, mat area
CT-->>UC: mem_array* result
end
UC->>UC: filter_tag_arr(min_values)
UC->>UC: filter_data_arr(min_values)
UC->>UCA: UCA(tag_arr, data_arr)
UCA->>UCA: combine via Htree2 routing
UCA-->>UC: uca_org_t (access_time, power, area)
UC-->>CI: fin_res
CI-->>AW: uca_org_t result
Key Classes
| # | Class | Header | Inherits | Purpose |
|---|---|---|---|---|
| 1 | Component | component.h | — | Base class: Area area, powerDef power/rt_power, double delay/cycle_time. Common base for all CACTI objects. |
| 2 | UCA | uca.h | Component | Unified Cache Architecture — combines tag + data banks with H-tree routing. Supports sequential, parallel, and fast access modes. |
| 3 | Bank | bank.h | Component | Bank-level aggregation of Mat objects. Calculates bank delay through row decoder → bitline → sense-amp → output mux. |
| 4 | Mat | mat.h | Component | Core computational unit (~82 KB). Models subarray-level timing: wordline, bitline delay, sense-amp, column mux, pre-charge circuits. |
| 5 | Subarray | subarray.h | Component | Physical cell array: dimensions from cell size × row × col counts. Computes parasitic Cwl, Rwl, Cbl. |
| 6 | Wire | wire.h | Component | Wire delay/power with repeater optimization. Types: Global, Global_5/10/20/30, Low_swing. Static per-technology tables. |
| 7 | Decoder | decoder.h | Component | Multi-stage NAND/NOR row/column decoders. Logical-effort-based gate sizing for minimum delay. |
| 8 | Predec | decoder.h | Component | Hierarchical predecoder: two PredecBlk + two PredecBlkDrv. First stage of address decoding. |
| 9 | PredecBlk | decoder.h | Component | Predecoder block — NAND2/NAND3 tree with dual paths for balanced delay. |
| 10 | Driver | decoder.h | Component | General-purpose buffer/driver circuit. Logical effort gate sizing across multiple stages. |
| 11 | Htree2 | htree2.h | Component | H-tree signal distribution: address, data-in, data-out across banks. Supports repeater insertion and low-swing signaling. |
| 12 | Crossbar | crossbar.h | Component | N × M tri-state buffer switch matrix. Area/power scales with port count and flit size. |
| 13 | MCPAT_Router | router.h | Component | 2D mesh router: crossbar + VC buffers + arbiter. Used by NoC and NUCA models. |
| 14 | MCPAT_Arbiter | arbiter.h | Component | VC arbitration logic: priority encoding, request/grant generation. Stages: arb_req → arb_pri → arb_grant. |
| 15 | Nuca | nuca.h | Component | Non-Uniform Cache Architecture: mesh-based cache with routers. Variable-latency access based on hop distance. |
| 16 | HighRadix | highradix.h | Component | High-radix router with sub-switch decomposition, row/column buffers, and multi-stage crossbar. |
| 17 | Area | area.h | — | Simple 2D geometry container: width × height with area calculation helpers. |
Data Structures
| Type | Name | Header | Description |
|---|---|---|---|
| class | powerComponents | cacti_interface.h | Power breakdown: dynamic, leakage, gate_leakage, short_circuit, longer_channel_leakage. |
| class | powerDef | cacti_interface.h | Per-operation power: readOp, writeOp, searchOp — each a powerComponents. |
| class | InputParameter | cacti_interface.h | Cache geometry input: cache_sz, line_sz, assoc, nbanks, ports, technology, optimization weights. |
| class | TechnologyParameter | cacti_interface.h | Nested DeviceType (Vth, I_on/off, C_gate) and InterconnectType (pitch, R/C per µm). Global instance: g_tp. |
| class | DynamicParameter | parameter.h | Runtime partition factors: Ndwl, Ndbl, Nspd, Ndsam, subarray dimensions, port counts. |
| struct | uca_org_t | cacti_interface.h | Solution struct: mem_array *tag_array2/data_array2, combined access_time, cycle_time, area, power. |
| struct | mem_array | cacti_interface.h | Single array partition result: Ndwl, Ndbl, Nspd, mux degrees, timing, area, power. |
| struct | results_mem_array | cacti_interface.h | Detailed output: all sub-component delays, power breakdowns, area efficiency, DRAM refresh power. |
| class | min_values_t | Ucache.h | Tracks optimization minima: min_delay, min_dyn, min_leakage, min_area, min_cyc. |
| struct | solution | Ucache.h | Single design point: tag/data array indices, access_time, cycle_time, area, efficiency, total_power. |
| struct | nuca_org_t | nuca.h | NUCA solution: bank/wire/router power-delay-area, contention, hop count, grid dimensions. |
| enum | Wire_type | cacti_interface.h | Global, Global_5/10/20/30, Low_swing, Semi_global, Transmission, Optical. |
Interactions with AccelWattch
CACTI is the analytical engine underneath AccelWattch. Every on-chip SRAM/CAM structure in the GPU power model is dimensioned by CACTI.
| Direction | Partner (AccelWattch) | Interface | Description |
|---|---|---|---|
| ← | ArrayST (array.h) | cacti_interface(InputParameter*) | Primary entry point. ArrayST wraps CACTI’s uca_org_t for every SRAM/CAM array (caches, TLBs, register files, BTBs). |
| ← | ArrayST::optimize_array() | cacti_interface() in loop | Iteratively calls CACTI with relaxed timing constraints to find minimum-energy array configuration. |
| ← | interconnect | Wire(type, length) | AccelWattch’s interconnect module wraps CACTI’s Wire class for bus power/delay modeling. |
| ← | SharedCache | ArrayST → cacti_interface() | L2/L3 cache power models delegate to CACTI through ArrayST for each cache bank. |
| ← | Core::InstFetchU | ArrayST (icache, BTB) | Instruction cache, branch target buffer, branch predictor arrays all sized via CACTI. |
| ← | Core::LoadStoreU | ArrayST (dcache, shmem) | Data cache, constant cache, texture cache, shared memory arrays all modeled by CACTI. |
| ← | Core::EXECU::RegFU | ArrayST (IRF, FRF) | Integer and floating-point register files dimensioned as SRAM arrays via CACTI. |
| ← | NoC | MCPAT_Router | Network-on-chip router model uses CACTI’s crossbar, arbiter, and buffer components. |
| → | technology.cc | g_tp (global) | CACTI provides ITRS-based technology parameters (22–180 nm) consumed by all AccelWattch components. |
Configuration Knobs
CACTI accepts cache geometry via InputParameter (programmatic API) or cache.cfg (file-based). Key parameters:
| Knob / Parameter | Field / Config | Default | Description |
|---|---|---|---|
| Cache size | cache_sz / -size (bytes) | 1 GB | Total cache capacity in bytes. |
| Block size | line_sz / -block size (bytes) | 64 | Cache line (block) size in bytes. |
| Associativity | assoc / -associativity | 8 | Set associativity. 0 = fully associative. |
| Bank count | nbanks / -UCA bank count | 1 | Number of UCA banks connected by H-tree. |
| Technology node | F_sz_nm / -technology (u) | 0.022 µm | Feature size. Supports 22, 32, 45, 65, 90, 180 nm. |
| Read-write ports | num_rw_ports | 1 | Number of read-write ports on the array. |
| Exclusive read ports | num_rd_ports | 0 | Number of read-only ports. |
| Exclusive write ports | num_wr_ports | 0 | Number of write-only ports. |
| Cell type (data) | ram_cell_tech_type | itrs-hp | Transistor type for data cells: itrs-hp, itrs-lstp, itrs-lop, lp-dram, comm-dram. |
| Cell type (tag) | tag_arr_ram_cell_tech_type | itrs-hp | Transistor type for tag array cells. |
| Access mode | access_mode | normal | normal (parallel tag/data), sequential, or fast (way prediction). |
| Wire type | wt | Global | Wire model: Global, Global_5–30, Low_swing, Semi_global. |
| Temperature | temp | 360 K | Operating temperature for leakage calculation. |
| Optimization target | obj_func_* | balanced | Weights for delay, dynamic power, leakage power, cycle time, area in the objective function. |
| H-tree repeaters | rpters_in_htree | true | Insert repeaters in H-tree routing wires. |
| Page size (DRAM) | page_sz | 8192 bits | DRAM page size for main memory modeling. |
Directory Map
Source tree for cacti/
cacti/
├── cacti_interface.h/.cc ← Public API: InputParameter, powerDef, uca_org_t, cacti_interface()
├── Ucache.h/.cc ← Unified cache solver: solve(), filter_tag_arr(), filter_data_arr()
├── uca.h/.cc ← Unified Cache Architecture: tag+data banks + H-tree assembly
├── bank.h/.cc ← Bank-level model: mat aggregation + H-tree routing
├── mat.h/.cc ← Mat (matrix) model: bitline/wordline delay, sense-amp, mux (~82 KB)
├── subarray.h/.cc ← Subarray cell array: physical dimensions, parasitic R/C
├── decoder.h/.cc ← Row/column decoders + predecoders (Predec, PredecBlk, Driver)
├── wire.h/.cc ← Wire delay/power: repeater insertion, low-swing, 5 wire types
├── htree2.h/.cc ← H-tree routing: address, data-in, data-out distribution
├── area.h/.cc ← Area accounting: width × height geometry container
├── component.h/.cc ← Base Component class: area, power, delay, gate-level helpers
├── parameter.h/.cc ← DynamicParameter: runtime partition factors from InputParameter
├── router.h/.cc ← MCPAT_Router: 2D mesh router (crossbar + VC buffers + arbiter)
├── crossbar.h/.cc ← Crossbar switch: N×M tri-state buffer matrix
├── arbiter.h/.cc ← Arbiter logic: VC arbitration, priority encoding, grant signals
├── nuca.h/.cc ← Non-Uniform Cache Architecture: mesh routing + contention
├── highradix.h/.cc ← High-radix router: sub-switch decomposition, row/col buffers
├── basic_circuit.h/.cc ← Transistor primitives: leakage, capacitance, logical effort
├── technology.cc ← ~130 KB ITRS technology database (22–180 nm nodes)
├── io.h/.cc ← I/O and reporting: config parsing, result formatting (~84 KB)
├── const.h ← Array size limits, Vth constants, gate type enums
├── main.cc ← Standalone CACTI entry point (command-line tool)
├── cache.cfg ← Default cache configuration file
├── cacti.mk ← Makefile fragment for CACTI library build
├── cacti.i ← SWIG interface (Python/Perl bindings)
├── README ← Original HP Labs CACTI readme
├── batch_tests/ ← Batch test scripts
├── contention.dat ← Contention lookup table for NUCA
└── out_batch_test_result.csv ← Sample batch test output
Deep-Dive Highlights
Core mechanisms from the CACTI sub-module have been extracted into dedicated focus areas. Each covers one subsystem with diagrams, code walks, and configuration details.
Deep-Dive Pages
Cache Timing Model Focus
How Mat computes the critical path: wordline driver → bitline discharge → sense amplifier → column mux → output driver. Covers compute_bitline_delay(), compute_sa_delay(), and compute_cam_delay() with RC circuit modeling.
Area Estimation Engine Focus
How CACTI computes die area from cell dimensions through subarray, mat, bank, to full cache. Covers Subarray::get_total_cell_area(), mat layout with decoders, H-tree overhead, and uca_org_t::adjust_area() for McPAT routing overhead.
Wire Delay & Power Model Focus
CACTI’s interconnect modeling: RC wire delay, optimal repeater insertion, low-swing differential signaling, and the 5 Global wire penalty variants (Global_5 through Global_30). Covers delay_optimal_wire(), wire_cap(), wire_res(), and H-tree composition.
Code Examples
Example 1: Calling CACTI from AccelWattch
// array.cc — ArrayST calls CACTI to size an SRAM array
ArrayST::ArrayST(const InputParameter *ip, string name, ...) {
l_ip = *ip; // copy cache geometry into local InputParameter
l_ip.error_checking();
// Call CACTI solver — returns timing, area, power
local_result = cacti_interface(&l_ip);
// Extract results into Component base class fields
area.set_area(local_result.area * 1e6); // mm² → µm²
power = local_result.power;
delay = local_result.access_time;
cycle_time = local_result.cycle_time;
}
Example 2: Multi-threaded Partition Search (solve)
// Ucache.cc — exhaustive search over partition space
void solve(uca_org_t *fin_res) {
init_tech_params(g_ip->F_sz_um, false);
list<mem_array *> tag_arr(0), data_arr(0);
// Spawn N threads, each searching a slice of the
// (Ndwl × Ndbl × Nspd × Ndcm × Ndsam) partition space
calc_time_mt_wrapper_struct *calc_array =
new calc_time_mt_wrapper_struct[nthreads];
pthread_t threads[nthreads];
for (uint32_t t = 0; t < nthreads; t++) {
calc_array[t].tid = t;
calc_array[t].pure_ram = pure_ram;
pthread_create(&threads[t], NULL,
calc_time_mt_wrapper, &calc_array[t]);
}
for (uint32_t t = 0; t < nthreads; t++)
pthread_join(threads[t], NULL);
// Merge results and filter dominated solutions
filter_tag_arr(&data_min, tag_arr);
filter_data_arr(data_arr);
// Combine best tag + data arrays via UCA/Htree
// → fin_res contains optimal (access_time, power, area)
}
Example 3: Wire Delay with Repeater Optimization
// wire.cc — optimal repeater insertion for global wires
void Wire::delay_optimal_wire() {
double len = wire_length;
double r = wire_res(len); // total wire resistance
double c = wire_cap(len); // total wire capacitance
// Elmore delay without repeaters: τ = 0.5·R·C
// With repeaters: insert every spacing_opt with size_opt
repeater_spacing = sqrt(
2 * deviceType->R_nch_on * deviceType->C_g_ideal /
(wire_res(1) * wire_cap(1)));
repeater_size =
sqrt(wire_res(1) * wire_cap(1) /
(deviceType->R_nch_on * deviceType->C_g_ideal));
// Calculate buffered wire delay
delay = repeater_spacing * wire_res(repeater_spacing) *
(wire_cap(repeater_spacing) +
deviceType->C_g_ideal * repeater_size);
power.readOp.dynamic = 0.5 * repeater_size *
deviceType->C_g_ideal * g_tp.peri_global.Vdd *
g_tp.peri_global.Vdd * (len / repeater_spacing);
}