Search in sources :

Example 11 with ContextEdge

use of com.jopdesign.common.code.CallGraph.ContextEdge in project jop by jop-devel.

the class ObjectCacheEvaluation method evaluateObjectCache.

private void evaluateObjectCache(MethodInfo targetMethod) throws InvalidFlowFactException, LpSolveException {
    long start, stop;
    // Method Cache
    //testExactAllFit();
    // Object Cache (debugging)
    ObjectCache objectCache = project.getWCETProcessorModel().getObjectCache();
    if (objectCache == null) {
        throw new AssertionError("Cannot evaluate object cache on a processor without object cache");
    }
    ObjectCacheAnalysis ocAnalysis = new ObjectCacheAnalysis(project, objectCache);
    // ocAnalysis.false, 1, 65536, ObjectCacheAnalysisDemo.DEFAULT_SET_SIZE);
    TopologicalOrderIterator<ExecutionContext, ContextEdge> cgIter = this.project.getCallGraph().topDownIterator();
    while (cgIter.hasNext()) {
        ExecutionContext scope = cgIter.next();
        Set<SymbolicAddress> addresses = ocAnalysis.getAddressSet(scope);
        String entryString = String.format("%-50s ==> |%d|%s ; Saturated Types: (%s)", scope, addresses.size(), ocAnalysis.getAddressSet(scope), ocAnalysis.getSaturatedTypes(scope));
        System.out.println("  " + entryString);
    }
    // Object cache, evaluation
    PrintStream pStream;
    ExecHelper.TeePrintStream oStream;
    try {
        pStream = new PrintStream(project.getProjectConfig().getOutFile("ocache", "eval.txt"));
        oStream = new ExecHelper.TeePrintStream(System.out, pStream);
    } catch (FileNotFoundException e) {
        oStream = new ExecHelper.TeePrintStream(System.out, null);
    }
    ObjectCacheAnalysisDemo oca;
    ObjectCacheTiming[] configs = { // sram,uni:  2 cycles field cost, 2*w cycles line cost
    new OCTimingUni(0, 0, 2), // sdram,uni: 10+2*w cycles for each w-word access
    new OCTimingUni(0, 10, 2), // SRAM, cmp, 2 cycles word load cost, s=2
    new OCTimingCmp(8, 1, 0, 0, 2), // SDRAM, cmp, 18 cycles quadword load cost, s=18
    new OCTimingCmp(8, 4, 0, 10, 2) };
    OCacheMode[] modes = { OCacheMode.BLOCK_FILL, OCacheMode.SINGLE_FIELD };
    List<OCacheAnalysisResult> samples = new ArrayList<OCacheAnalysisResult>();
    // need to be in ascending order
    int[] cacheWays = { 0, 2, 4, 8, 16, 32, 64, 512 };
    int[] lineSizesObjCache = { 4, 8, 16, 32 };
    int[] lineSizesFieldCache = { 1 };
    int[] blockSizesObjCache = { 1, 2, 4, 8, 16 };
    int[] lineSizes;
    for (int configId = 0; configId < configs.length; configId++) {
        ObjectCacheTiming ocConfig = configs[configId];
        oStream.println("---------------------------------------------------------");
        oStream.println("Object Cache Configuration: " + ocConfig);
        oStream.println("---------------------------------------------------------");
        for (OCacheMode mode : modes) {
            long maxCost = 0;
            //			long cacheMisses = Long.MAX_VALUE;
            String modeString;
            lineSizes = lineSizesObjCache;
            if (mode == OCacheMode.BLOCK_FILL)
                modeString = "fill-block";
            else {
                modeString = "field-as-tag";
                lineSizes = lineSizesFieldCache;
            }
            boolean first = true;
            for (int lineSize : lineSizes) {
                for (int blockSize : blockSizesObjCache) {
                    if (blockSize > lineSize)
                        continue;
                    if (mode == OCacheMode.BLOCK_FILL) {
                    } else {
                        if (blockSize > 1)
                            continue;
                    }
                    /* Configure object cache timing */
                    /* We have to take field access count of cache size = 0; our analysis otherwise does not assign
						 * sensible field access counts (thats the fault of the IPET method)
						 */
                    long totalFieldAccesses = -1, cachedFieldAccesses = -1;
                    double bestCyclesPerAccessForConfig = Double.POSITIVE_INFINITY;
                    double bestHitRate = 0.0;
                    long bestCostPerConfig = Long.MAX_VALUE;
                    // assume cacheSizes are in ascending order
                    for (int ways : cacheWays) {
                        ocConfig.setObjectCacheTiming(objectCache, blockSize);
                        if (mode == OCacheMode.SINGLE_FIELD) {
                            objectCache = ObjectCache.createFieldCache(project, ways, 0, 0, 0);
                        } else {
                            objectCache = new ObjectCache(project, ways, blockSize, lineSize, 0, 0, 0);
                        }
                        ocConfig.setObjectCacheTiming(objectCache, blockSize);
                        oca = new ObjectCacheAnalysisDemo(project, objectCache);
                        double cyclesPerAccess, hitRate;
                        ObjectCache.ObjectCacheCost ocCost = oca.computeCost();
                        long cost = ocCost.getCost();
                        if (cost < bestCostPerConfig)
                            bestCostPerConfig = cost;
                        double bestRatio, ratio;
                        if (ways == 0) {
                            maxCost = cost;
                            totalFieldAccesses = ocCost.getTotalFieldAccesses();
                            cachedFieldAccesses = ocCost.getFieldAccessesWithoutBypass();
                            bestRatio = 1.0;
                            ratio = 1.0;
                        } else {
                            bestRatio = (double) bestCostPerConfig / (double) maxCost;
                            ratio = (double) cost / (double) maxCost;
                        }
                        cyclesPerAccess = (double) cost / (double) totalFieldAccesses;
                        if (cyclesPerAccess < bestCyclesPerAccessForConfig || ways <= 1) {
                            bestCyclesPerAccessForConfig = cyclesPerAccess;
                        }
                        /* hit rate is defined as: 1 - ((cache misses+accesses to bypassed fields) / total field accesses (with n=0) */
                        long missAccesses = ocCost.getCacheMissCount() + ocCost.getBypassCount();
                        hitRate = (1 - ((double) missAccesses / (double) totalFieldAccesses));
                        if (hitRate > bestHitRate || ways <= 1) {
                            bestHitRate = hitRate;
                        }
                        if (first) {
                            oStream.println(String.format("***** ***** MODE = %s ***** *****\n", modeString));
                            oStream.println(String.format(" - max tags accessed (upper bound) = %d, max fields accesses = %d", oca.getMaxAccessedTags(targetMethod, CallString.EMPTY), totalFieldAccesses));
                            first = false;
                        }
                        String report = //, %.2f %% 'hitrate')", 
                        String.format(//, %.2f %% 'hitrate')", 
                        " + Cycles Per Access [N=%3d,l=%2d,b=%2d]: %.2f (%d total cost, %.2f %% cost of no cache, %d bypass cost)", ways, lineSize, blockSize, bestCyclesPerAccessForConfig, cost, bestRatio * 100, ocCost.getBypassCost());
                        if (bestCostPerConfig > cost) {
                            report += String.format(" # (analysis cost increased by %.2f %% for this associativity)", ratio * 100);
                        }
                        oStream.println(report);
                        if (mode != OCacheMode.SINGLE_FIELD) {
                            OCacheAnalysisResult sample = new ObjectCacheEvaluationResult.OCacheAnalysisResult(ways, lineSize, blockSize, configId, bestHitRate, bestCyclesPerAccessForConfig, ocCost);
                            samples.add(sample);
                        }
                    }
                }
            }
        }
    }
    OCacheAnalysisResult.dumpBarPlot(samples, oStream);
    OCacheAnalysisResult.dumpPlot(samples, oStream);
    OCacheAnalysisResult.dumpLatex(samples, oStream);
}
Also used : OCacheAnalysisResult(com.jopdesign.wcet.analysis.cache.ObjectCacheEvaluationResult.OCacheAnalysisResult) FileNotFoundException(java.io.FileNotFoundException) ArrayList(java.util.ArrayList) ObjectCacheAnalysis(com.jopdesign.wcet.analysis.cache.ObjectCacheAnalysis) CallString(com.jopdesign.common.code.CallString) ObjectCache(com.jopdesign.wcet.jop.ObjectCache) SymbolicAddress(com.jopdesign.dfa.analyses.SymbolicAddress) PrintStream(java.io.PrintStream) ObjectCacheCost(com.jopdesign.wcet.jop.ObjectCache.ObjectCacheCost) ContextEdge(com.jopdesign.common.code.CallGraph.ContextEdge) OCacheMode(com.jopdesign.wcet.analysis.cache.ObjectCacheEvaluationResult.OCacheMode) ExecutionContext(com.jopdesign.common.code.ExecutionContext) ObjectCacheAnalysisDemo(com.jopdesign.wcet.analysis.cache.ObjectCacheAnalysisDemo)

Aggregations

ContextEdge (com.jopdesign.common.code.CallGraph.ContextEdge)11 ExecutionContext (com.jopdesign.common.code.ExecutionContext)11 MethodInfo (com.jopdesign.common.MethodInfo)7 LinkedHashSet (java.util.LinkedHashSet)4 DFSTraverser (com.jopdesign.common.graphutils.DFSTraverser)3 EmptyDFSVisitor (com.jopdesign.common.graphutils.DFSTraverser.EmptyDFSVisitor)3 ControlFlowGraph (com.jopdesign.common.code.ControlFlowGraph)2 CFGNode (com.jopdesign.common.code.ControlFlowGraph.CFGNode)2 FileNotFoundException (java.io.FileNotFoundException)2 ArrayList (java.util.ArrayList)2 Set (java.util.Set)2 TopologicalOrderIterator (org.jgrapht.traverse.TopologicalOrderIterator)2 ClassInfo (com.jopdesign.common.ClassInfo)1 MethodCode (com.jopdesign.common.MethodCode)1 CallGraph (com.jopdesign.common.code.CallGraph)1 CallString (com.jopdesign.common.code.CallString)1 BasicBlockNode (com.jopdesign.common.code.ControlFlowGraph.BasicBlockNode)1 InvokeNode (com.jopdesign.common.code.ControlFlowGraph.InvokeNode)1 Segment (com.jopdesign.common.code.Segment)1 DFSEdgeType (com.jopdesign.common.graphutils.DFSTraverser.DFSEdgeType)1