model "ACG" uses "mmxprs" declarations processors = 3 !Number of processors units = 7 !Number of memory units possible at each level. levels = 2 ! number of levels possible in the mem hierarchy memsize = 7 ! Total size of the available memory. blocknum = 7 ! Number of data blocks. blocksize = 1 ! Block size phases = 2 ! Number of data access phases !accesses = 10 ! Number of accesses per phase level_total = (levels) + (levels-1) + (levels-2) SUBSET : array(1..units, 1..units) of integer ! Indicates which memory component can be a subset of which one ACCESSES: array(1..processors, 1..phases, 1..blocknum) of integer ! Data access sequence on each program phase LOCAL: array(1..processors, 1..units) of integer ! Maximum possible memory size of each level PORTS_E: array(1..units) of integer ! Energy effect of ports in units component: array(1..levels,1..units,0..memsize) of mpvar ! Each mem component on a level has a size map: array(1..phases,1..blocknum,1..levels,1..units,0..memsize) of mpvar ! At each phase a data block is mapped to a memory component on a level with a size. processor_phase: array(1..processors, 1..phases) of mpvar ! Energy cost of each processor at each phase. end-declarations initializations from 'memhier-input.dat' SUBSET ACCESSES LOCAL PORTS_E end-initializations ! Total memory should be equal to the sizes of different components. sum(l in 1..levels, u in 1..units, m in 0..memsize) m * component(l,u,m) = memsize ! A memory unit can have a single size forall(l in 1..levels, u in 1..units) sum(m in 0..memsize) component(l,u,m) = 1 ! The maximum size possible is limited for every level forall(l in 1..levels-1) sum(u in 1..units, m in 0..memsize) m * component(l,u,m) <= ceil((memsize * l)/level_total) ! A lower level memory component has to be in the subset of an upper level forall(l in 2..levels, u1 in 1..units, m1 in 1..memsize ) component(l-1,u1,m1) <= sum(u2 in 1..units, m2 in 1..memsize | m2>m1 and SUBSET(u2,u1)=1) component(l,u2,m2) ! A memory component in an upper level should have a larger size than the same component's lower version forall(l1,l2 in 1..levels, u in 1..units, m1,m2 in 1..memsize | m1>=m2 and l2>l1) component(l1,u,m1) <= 1-component(l2,u,m2) ! A data is mapped to a single memory unit. forall(b in 1..blocknum,ph in 1..phases) sum(l in 1..levels,u in 1..units,m in 0..memsize) map(ph,b,l,u,m) = 1 ! If a memory component is used for a data block it has to exist forall(ph in 1..phases, b in 1..blocknum, l in 1..levels, u in 1..units, m in 0..memsize) component(l,u,m) >= map(ph,b,l,u,m) ! Data stored in a unit must be less than the size of the unit forall(ph in 1..phases, l in 1..levels, u in 1..units, m in 0..memsize) sum(b in 1..blocknum) map(ph,b,l,u,m) * blocksize <= m ! Each processor's access cost can be calculated as follows: forall(p in 1..processors, ph in 1..phases) processor_phase(p,ph)=sum(b in 1..blocknum, l in 1..levels, u in 1..units, m in 1..memsize) map(ph,b,l,u,m) * ACCESSES(p,ph,b)* (2 - (1 * LOCAL(p,u))) * (l^2) * (1+m*.001) * (1 + PORTS_E(u)*.05) ! Binary definitions. forall(l in 1..levels,u in 1..units,m in 0..memsize) component(l,u,m) is_binary forall(ph in 1..phases,b in 1..blocknum,l in 1..levels,u in 1..units,m in 0..memsize) map(ph,b,l,u,m) is_binary !total processor cost access_cost:=sum(p in 1..processors, ph in 1..phases ) processor_phase(p,ph) minimize(access_cost) writeln("Total cost: \t", getobjval) writeln(""); forall(l in 1..levels, u in 1..units, m in 1..memsize) if(getsol(component(l,u,m))>0) then writeln("level ",l," unit ",u," (size: ",m,") exists.") end-if writeln(""); forall(ph in 1..phases, b in 1..blocknum, l in 1..levels, u in 1..units, m in 0..memsize, k in 1..units) if(getsol(map(ph,b,l,u,m))>0) then writeln("at phase ",ph," block ",b," is located at level ",l," unit ",u," (size: ",m,").") end-if writeln(""); end-model