Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/device/cpu.cfa

    r1f05c83 rcf85f96  
    253253        }
    254254
    255         #if defined(__CFA_WITH_VERIFY__)
    256                 // Check widths are consistent
    257                 for(i; 1~cpus) {
    258                         for(j; cache_levels) {
    259                                 verifyf(raw[0][j].width == raw[i][j].width, "Unexpected width %u for cpu %u, index %u. Expected %u.", raw[i][j].width, i, j, raw[0][j].width);
    260                         }
    261                 }
    262         #endif
    263 
    264255        return raw;
    265256}
    266257
     258struct llc_map_t {
     259        raw_cache_instance * raw;
     260        unsigned count;
     261        unsigned start;
     262};
     263
    267264// returns an allocate list of all the different distinct last level caches
    268 static [*idx_range_t, size_t cnt] distinct_llcs(unsigned cpus, unsigned llc_idx, raw_cache_instance ** raw) {
     265static [*llc_map_t, size_t cnt] distinct_llcs(unsigned cpus, unsigned llc_idx, raw_cache_instance ** raw) {
    269266        // Allocate at least one element
    270         idx_range_t * ranges = alloc();
     267        llc_map_t* ranges = alloc();
    271268        size_t range_cnt = 1;
    272269
    273270        // Initialize with element 0
    274         *ranges = raw[0][llc_idx].range;
     271        ranges->raw = &raw[0][llc_idx];
     272        ranges->count = 0;
     273        ranges->start = -1u;
    275274
    276275        // Go over all other cpus
    277276        CPU_LOOP: for(i; 1~cpus) {
    278277                // Check if the range is already there
    279                 idx_range_t candidate = raw[i][llc_idx].range;
     278                raw_cache_instance * candidate = &raw[i][llc_idx];
    280279                for(j; range_cnt) {
    281                         idx_range_t exist = ranges[j];
     280                        llc_map_t & exist = ranges[j];
    282281                        // If the range is already there just jump to the next cpu
    283                         if(0 == strcmp(candidate, exist)) continue CPU_LOOP;
     282                        if(0 == strcmp(candidate->range, exist.raw->range)) continue CPU_LOOP;
    284283                }
    285284
    286285                // The range wasn't there, added to the list
    287286                ranges = alloc(range_cnt + 1, ranges`realloc);
    288                 ranges[range_cnt] = candidate;
     287                ranges[range_cnt].raw = candidate;
     288                ranges[range_cnt].count = 0;
     289                ranges[range_cnt].start = -1u;
    289290                range_cnt++;
    290291        }
     
    296297struct cpu_pairing_t {
    297298        unsigned cpu;
    298         unsigned llc_id;
     299        unsigned id;
    299300};
    300301
    301302int ?<?( cpu_pairing_t lhs, cpu_pairing_t rhs ) {
    302         return lhs.llc_id < rhs.llc_id;
    303 }
    304 
    305 static [[]cpu_pairing_t] get_cpu_pairings(unsigned cpus, raw_cache_instance ** raw, idx_range_t * maps, size_t map_cnt) {
     303        return lhs.id < rhs.id;
     304}
     305
     306static [[]cpu_pairing_t] get_cpu_pairings(unsigned cpus, raw_cache_instance ** raw, llc_map_t * maps, size_t map_cnt) {
    306307        cpu_pairing_t * pairings = alloc(cpus);
    307308
     
    310311                idx_range_t want = raw[i][0].range;
    311312                MAP_LOOP: for(j; map_cnt) {
    312                         if(0 != strcmp(want, maps[j])) continue MAP_LOOP;
    313 
    314                         pairings[i].llc_id = j;
     313                        if(0 != strcmp(want, maps[j].raw->range)) continue MAP_LOOP;
     314
     315                        pairings[i].id = j;
    315316                        continue CPU_LOOP;
    316317                }
     
    321322        return pairings;
    322323}
     324
     325#include <fstream.hfa>
    323326
    324327extern "C" {
     
    345348
    346349                // Find number of distinct cache instances
    347                 idx_range_t * maps;
     350                llc_map_t * maps;
    348351                size_t map_cnt;
    349352                [maps, map_cnt] =  distinct_llcs(cpus, cache_levels - llc, raw);
    350353
    351                 /* paranoid */ verify((map_cnt * raw[0][cache_levels - llc].width) == cpus);
     354                #if defined(__CFA_WITH_VERIFY__)
     355                // Verify that the caches cover the all the cpus
     356                {
     357                        unsigned width1 = 0;
     358                        unsigned width2 = 0;
     359                        for(i; map_cnt) {
     360                                const char * _;
     361                                width1 += read_width(maps[i].raw->range, strlen(maps[i].raw->range), &_);
     362                                width2 += maps[i].raw->width;
     363                        }
     364                        verify(width1 == cpus);
     365                        verify(width2 == cpus);
     366                }
     367                #endif
    352368
    353369                // Get mappings from cpu to cache instance
     
    357373                qsort(pairings, cpus);
    358374
    359                 unsigned llc_width = raw[0][cache_levels - llc].width;
    360 
    361                 // From the mappins build the actual cpu map we want
     375                {
     376                        unsigned it = 0;
     377                        for(i; cpus) {
     378                                unsigned llc_id = pairings[i].id;
     379                                if(maps[llc_id].start == -1u) {
     380                                        maps[llc_id].start = it;
     381                                        it += maps[llc_id].raw->width;
     382                                        /* paranoid */ verify(maps[llc_id].start < it);
     383                                        /* paranoid */ verify(it != -1u);
     384                                }
     385                        }
     386                        /* paranoid */ verify(it == cpus);
     387                }
     388
     389                // From the mappings build the actual cpu map we want
    362390                struct cpu_map_entry_t * entries = alloc(cpus);
    363391                for(i; cpus) { entries[i].count = 0; }
    364392                for(i; cpus) {
     393                        /* paranoid */ verify(pairings[i].id < map_cnt);
    365394                        unsigned c = pairings[i].cpu;
    366                         entries[c].start = pairings[i].llc_id * llc_width;
    367                         entries[c].count = llc_width;
     395                        unsigned llc_id = pairings[i].id;
     396                        unsigned width = maps[llc_id].raw->width;
     397                        unsigned start = maps[llc_id].start;
     398                        unsigned self  = start + (maps[llc_id].count++);
     399                        entries[c].count = width;
     400                        entries[c].start = start;
     401                        entries[c].self  = self;
    368402                }
    369403
Note: See TracChangeset for help on using the changeset viewer.