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.

15+
Classes
41
Source Files
~18.8 k
Lines of Code
22–180
nm Nodes
5
Wire Models

📚 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

#ClassHeaderInheritsPurpose
1Componentcomponent.h—Base class: Area area, powerDef power/rt_power, double delay/cycle_time. Common base for all CACTI objects.
2UCAuca.hComponentUnified Cache Architecture — combines tag + data banks with H-tree routing. Supports sequential, parallel, and fast access modes.
3Bankbank.hComponentBank-level aggregation of Mat objects. Calculates bank delay through row decoder → bitline → sense-amp → output mux.
4Matmat.hComponentCore computational unit (~82 KB). Models subarray-level timing: wordline, bitline delay, sense-amp, column mux, pre-charge circuits.
5Subarraysubarray.hComponentPhysical cell array: dimensions from cell size × row × col counts. Computes parasitic Cwl, Rwl, Cbl.
6Wirewire.hComponentWire delay/power with repeater optimization. Types: Global, Global_5/10/20/30, Low_swing. Static per-technology tables.
7Decoderdecoder.hComponentMulti-stage NAND/NOR row/column decoders. Logical-effort-based gate sizing for minimum delay.
8Predecdecoder.hComponentHierarchical predecoder: two PredecBlk + two PredecBlkDrv. First stage of address decoding.
9PredecBlkdecoder.hComponentPredecoder block — NAND2/NAND3 tree with dual paths for balanced delay.
10Driverdecoder.hComponentGeneral-purpose buffer/driver circuit. Logical effort gate sizing across multiple stages.
11Htree2htree2.hComponentH-tree signal distribution: address, data-in, data-out across banks. Supports repeater insertion and low-swing signaling.
12Crossbarcrossbar.hComponentN × M tri-state buffer switch matrix. Area/power scales with port count and flit size.
13MCPAT_Routerrouter.hComponent2D mesh router: crossbar + VC buffers + arbiter. Used by NoC and NUCA models.
14MCPAT_Arbiterarbiter.hComponentVC arbitration logic: priority encoding, request/grant generation. Stages: arb_req → arb_pri → arb_grant.
15Nucanuca.hComponentNon-Uniform Cache Architecture: mesh-based cache with routers. Variable-latency access based on hop distance.
16HighRadixhighradix.hComponentHigh-radix router with sub-switch decomposition, row/column buffers, and multi-stage crossbar.
17Areaarea.h—Simple 2D geometry container: width × height with area calculation helpers.

Data Structures

TypeNameHeaderDescription
classpowerComponentscacti_interface.hPower breakdown: dynamic, leakage, gate_leakage, short_circuit, longer_channel_leakage.
classpowerDefcacti_interface.hPer-operation power: readOp, writeOp, searchOp — each a powerComponents.
classInputParametercacti_interface.hCache geometry input: cache_sz, line_sz, assoc, nbanks, ports, technology, optimization weights.
classTechnologyParametercacti_interface.hNested DeviceType (Vth, I_on/off, C_gate) and InterconnectType (pitch, R/C per µm). Global instance: g_tp.
classDynamicParameterparameter.hRuntime partition factors: Ndwl, Ndbl, Nspd, Ndsam, subarray dimensions, port counts.
structuca_org_tcacti_interface.hSolution struct: mem_array *tag_array2/data_array2, combined access_time, cycle_time, area, power.
structmem_arraycacti_interface.hSingle array partition result: Ndwl, Ndbl, Nspd, mux degrees, timing, area, power.
structresults_mem_arraycacti_interface.hDetailed output: all sub-component delays, power breakdowns, area efficiency, DRAM refresh power.
classmin_values_tUcache.hTracks optimization minima: min_delay, min_dyn, min_leakage, min_area, min_cyc.
structsolutionUcache.hSingle design point: tag/data array indices, access_time, cycle_time, area, efficiency, total_power.
structnuca_org_tnuca.hNUCA solution: bank/wire/router power-delay-area, contention, hop count, grid dimensions.
enumWire_typecacti_interface.hGlobal, 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.

DirectionPartner (AccelWattch)InterfaceDescription
←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 loopIteratively calls CACTI with relaxed timing constraints to find minimum-energy array configuration.
←interconnectWire(type, length)AccelWattch’s interconnect module wraps CACTI’s Wire class for bus power/delay modeling.
←SharedCacheArrayST → cacti_interface()L2/L3 cache power models delegate to CACTI through ArrayST for each cache bank.
←Core::InstFetchUArrayST (icache, BTB)Instruction cache, branch target buffer, branch predictor arrays all sized via CACTI.
←Core::LoadStoreUArrayST (dcache, shmem)Data cache, constant cache, texture cache, shared memory arrays all modeled by CACTI.
←Core::EXECU::RegFUArrayST (IRF, FRF)Integer and floating-point register files dimensioned as SRAM arrays via CACTI.
←NoCMCPAT_RouterNetwork-on-chip router model uses CACTI’s crossbar, arbiter, and buffer components.
→technology.ccg_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 / ParameterField / ConfigDefaultDescription
Cache sizecache_sz / -size (bytes)1 GBTotal cache capacity in bytes.
Block sizeline_sz / -block size (bytes)64Cache line (block) size in bytes.
Associativityassoc / -associativity8Set associativity. 0 = fully associative.
Bank countnbanks / -UCA bank count1Number of UCA banks connected by H-tree.
Technology nodeF_sz_nm / -technology (u)0.022 µmFeature size. Supports 22, 32, 45, 65, 90, 180 nm.
Read-write portsnum_rw_ports1Number of read-write ports on the array.
Exclusive read portsnum_rd_ports0Number of read-only ports.
Exclusive write portsnum_wr_ports0Number of write-only ports.
Cell type (data)ram_cell_tech_typeitrs-hpTransistor type for data cells: itrs-hp, itrs-lstp, itrs-lop, lp-dram, comm-dram.
Cell type (tag)tag_arr_ram_cell_tech_typeitrs-hpTransistor type for tag array cells.
Access modeaccess_modenormalnormal (parallel tag/data), sequential, or fast (way prediction).
Wire typewtGlobalWire model: Global, Global_5–30, Low_swing, Semi_global.
Temperaturetemp360 KOperating temperature for leakage calculation.
Optimization targetobj_func_*balancedWeights for delay, dynamic power, leakage power, cycle time, area in the objective function.
H-tree repeatersrpters_in_htreetrueInsert repeaters in H-tree routing wires.
Page size (DRAM)page_sz8192 bitsDRAM 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.

Mat • Decoder • Predec • Driver

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.

Subarray • Area • UCA • Bank

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.

Wire • Htree2 • basic_circuit

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);
}