Search in sources :

Example 1 with SymbolicAddress

use of com.jopdesign.dfa.analyses.SymbolicAddress in project jop by jop-devel.

the class ObjectCacheAnalysis method getSaturatedTypes.

/** Traverse vertex set. Collect those types where we could not resolve
	 * the symbolic object names. (Not too useful in the analysis, but useful
	 * for debugging)
	 */
public HashSet<String> getSaturatedTypes(Segment segment, LocalPointsToResult usedRefs) {
    HashSet<String> topTypes = new HashSet<String>();
    for (SuperGraphNode n : segment.getNodes()) {
        BasicBlock bb = n.getCFGNode().getBasicBlock();
        if (bb == null)
            continue;
        CallString cs = n.getContextCFG().getCallString();
        for (InstructionHandle ih : bb.getInstructions()) {
            BoundedSet<SymbolicAddress> refs;
            if (usedRefs.containsKey(ih)) {
                refs = usedRefs.get(ih, cs);
                String handleType = getHandleType(project, n.getCfg(), ih);
                if (handleType == null)
                    continue;
                if (refs.isSaturated()) {
                    topTypes.add(handleType);
                }
            }
        }
    }
    return topTypes;
}
Also used : BasicBlock(com.jopdesign.common.code.BasicBlock) SuperGraphNode(com.jopdesign.common.code.SuperGraph.SuperGraphNode) CallString(com.jopdesign.common.code.CallString) SymbolicAddress(com.jopdesign.dfa.analyses.SymbolicAddress) InstructionHandle(org.apache.bcel.generic.InstructionHandle) HashSet(java.util.HashSet) CallString(com.jopdesign.common.code.CallString)

Example 2 with SymbolicAddress

use of com.jopdesign.dfa.analyses.SymbolicAddress in project jop by jop-devel.

the class ObjectCacheAnalysis method getMaxCacheCost.

/**
	 * Get maximum cost due to the object cache in the given scope.
	 * Using special cost models such as COUNT_FIELD_TAGS and COUNT_REF_TAGS, this
	 * method can be used to calculate different metrics as well.
	 * <p> XXX: Use segment instead of scope </p>
	 * @param scope
	 * @param costModel The object cache cost model
	 * @return
	 * @throws InvalidFlowFactException 
	 * @throws LpSolveException 
	 */
public ObjectCacheCost getMaxCacheCost(ExecutionContext scope, ObjectCacheCostModel costModel) throws InvalidFlowFactException, LpSolveException {
    LocalPointsToResult usedRefs = getUsedRefs(scope);
    Segment segment = Segment.methodSegment(scope.getMethodInfo(), scope.getCallString(), project, project.getCallstringLength(), project);
    /* Compute worst-case cost */
    HashSet<SymbolicAddress> usedObjectsSet = new HashSet<SymbolicAddress>();
    return computeCacheCost(segment, usedRefs, costModel, usedObjectsSet);
}
Also used : SymbolicAddress(com.jopdesign.dfa.analyses.SymbolicAddress) Segment(com.jopdesign.common.code.Segment) HashSet(java.util.HashSet)

Example 3 with SymbolicAddress

use of com.jopdesign.dfa.analyses.SymbolicAddress 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)

Example 4 with SymbolicAddress

use of com.jopdesign.dfa.analyses.SymbolicAddress in project jop by jop-devel.

the class ObjectCacheAnalysis method addMissOnceCost.

/**
	 * Add miss once cost: for each method cache persistence segment, add maximum miss cost to the segment entries
	 * @param segment
	 * @param ipetSolver
	 * @param checks
	 * @throws LpSolveException 
	 * @throws InvalidFlowFactException 
	 */
@Override
public Set<SuperGraphEdge> addMissOnceCost(Segment segment, IPETSolver<SuperGraphEdge> ipetSolver, EnumSet<PersistenceCheck> checks) throws InvalidFlowFactException, LpSolveException {
    Set<SuperGraphEdge> missCostEdges = new HashSet<SuperGraphEdge>();
    Set<SuperGraphNode> alwaysMissNodes = new HashSet<SuperGraphNode>();
    Collection<Segment> cover = findPersistenceSegmentCover(segment, EnumSet.allOf(PersistenceCheck.class), false, alwaysMissNodes);
    int tag = 0;
    for (Segment persistenceSegment : cover) {
        tag++;
        /* Compute cost for persistence segment */
        HashSet<SymbolicAddress> usedSetOut = new HashSet<SymbolicAddress>();
        ObjectCacheCost cost = computeCacheCost(persistenceSegment, getUsedRefs(persistenceSegment), objectCache.getCostModel(), usedSetOut);
        WCETTool.logger.info("O$-addMissOnceCost: " + cost.toString());
        F1<SuperGraphEdge, Long> costModel = MiscUtils.const1(cost.getCost());
        Set<SuperGraphEdge> costEdges = addFixedCostEdges(persistenceSegment.getEntryEdges(), ipetSolver, costModel, KEY + "_miss_once", tag);
        missCostEdges.addAll(costEdges);
    }
    AccessCostInfo alwaysMissAccessInfo = extractAccessesAndCosts(alwaysMissNodes, null, objectCache.getCostModel());
    missCostEdges.addAll(addStaticCost(segment, alwaysMissAccessInfo, ipetSolver));
    return missCostEdges;
}
Also used : ObjectCacheCost(com.jopdesign.wcet.jop.ObjectCache.ObjectCacheCost) Segment(com.jopdesign.common.code.Segment) AccessCostInfo(com.jopdesign.wcet.analysis.cache.ObjectCacheAnalysis.AccessCostInfo) SuperGraphEdge(com.jopdesign.common.code.SuperGraph.SuperGraphEdge) SuperGraphNode(com.jopdesign.common.code.SuperGraph.SuperGraphNode) SymbolicAddress(com.jopdesign.dfa.analyses.SymbolicAddress) HashSet(java.util.HashSet)

Example 5 with SymbolicAddress

use of com.jopdesign.dfa.analyses.SymbolicAddress in project jop by jop-devel.

the class ObjectCacheAnalysis method extractAccessesAndCosts.

/** Traverse vertex set.
	 * <p>Add vertex to access set of referenced addresses
	 * For references whose type cannot be fully resolved, add a
	 * cost of 1.</p>
	 * <p>FIXME: We should deal with subtyping (or better use storage based alias-analysis)</p>
	 *
	 * @param nodes
	 * @param usedRefs the results of the local points-to analysis, or {@code null} for always miss costs
	 * @param costModel
	 */
private AccessCostInfo extractAccessesAndCosts(Iterable<SuperGraphNode> nodes, LocalPointsToResult usedRefs, ObjectCacheCostModel costModel) {
    AccessCostInfo aci = new AccessCostInfo();
    for (SuperGraphNode node : nodes) {
        /* Compute cost for basic block */
        BasicBlock bb = node.getCFGNode().getBasicBlock();
        if (bb == null)
            continue;
        long bypassCost = 0;
        long alwaysMissCost = 0;
        CallString cs = node.getContextCFG().getCallString();
        for (InstructionHandle ih : bb.getInstructions()) {
            String handleType = getHandleType(project, node.getCfg(), ih);
            if (handleType == null)
                continue;
            /* No getfield/handle access */
            int fieldIndex = getFieldIndex(project, node.getCfg(), ih);
            int blockIndex = getBlockIndex(fieldIndex);
            if (fieldIndex > this.maxCachedFieldIndex) {
                bypassCost += costModel.getFieldAccessCostBypass();
                continue;
            }
            BoundedSet<SymbolicAddress> refs = null;
            if (usedRefs != null) {
                if (!usedRefs.containsKey(ih)) {
                    usedRefs = null;
                    WCETTool.logger.error("No DFA results for: " + ih.getInstruction() + " with field " + ((FieldInstruction) ih.getInstruction()).getFieldName(bb.cpg()));
                } else {
                    refs = usedRefs.get(ih, cs);
                    if (refs.isSaturated())
                        refs = null;
                }
            }
            if (refs == null) {
                alwaysMissCost += costModel.getReplaceLineCost() + costModel.getLoadCacheBlockCost();
            } else {
                for (SymbolicAddress ref : refs.getSet()) {
                    aci.addRefAccess(ref, node);
                    aci.addBlockAccess(ref.accessArray(blockIndex), node);
                    // Handle getfield_long / getfield_double
                    if (getCachedType(project, node.getCfg(), ih) == Type.LONG || getCachedType(project, node.getCfg(), ih) == Type.DOUBLE) {
                        if (blockIndex + 1 > this.maxCachedFieldIndex) {
                            bypassCost += costModel.getFieldAccessCostBypass();
                        } else {
                            aci.addBlockAccess(ref.accessArray(blockIndex + 1), node);
                        }
                    }
                }
            }
        }
        aci.putBypassCost(node, bypassCost);
        aci.putStaticCost(node, bypassCost + alwaysMissCost);
    }
    return aci;
}
Also used : AccessCostInfo(com.jopdesign.wcet.analysis.cache.ObjectCacheAnalysis.AccessCostInfo) BasicBlock(com.jopdesign.common.code.BasicBlock) SuperGraphNode(com.jopdesign.common.code.SuperGraph.SuperGraphNode) CallString(com.jopdesign.common.code.CallString) FieldInstruction(org.apache.bcel.generic.FieldInstruction) SymbolicAddress(com.jopdesign.dfa.analyses.SymbolicAddress) InstructionHandle(org.apache.bcel.generic.InstructionHandle) CallString(com.jopdesign.common.code.CallString)

Aggregations

SymbolicAddress (com.jopdesign.dfa.analyses.SymbolicAddress)7 HashSet (java.util.HashSet)5 CallString (com.jopdesign.common.code.CallString)4 Segment (com.jopdesign.common.code.Segment)4 SuperGraphNode (com.jopdesign.common.code.SuperGraph.SuperGraphNode)4 AccessCostInfo (com.jopdesign.wcet.analysis.cache.ObjectCacheAnalysis.AccessCostInfo)3 BasicBlock (com.jopdesign.common.code.BasicBlock)2 SuperGraphEdge (com.jopdesign.common.code.SuperGraph.SuperGraphEdge)2 ObjectCacheCost (com.jopdesign.wcet.jop.ObjectCache.ObjectCacheCost)2 InstructionHandle (org.apache.bcel.generic.InstructionHandle)2 ContextEdge (com.jopdesign.common.code.CallGraph.ContextEdge)1 ExecutionContext (com.jopdesign.common.code.ExecutionContext)1 ObjectCacheAnalysis (com.jopdesign.wcet.analysis.cache.ObjectCacheAnalysis)1 ObjectCacheAnalysisDemo (com.jopdesign.wcet.analysis.cache.ObjectCacheAnalysisDemo)1 OCacheAnalysisResult (com.jopdesign.wcet.analysis.cache.ObjectCacheEvaluationResult.OCacheAnalysisResult)1 OCacheMode (com.jopdesign.wcet.analysis.cache.ObjectCacheEvaluationResult.OCacheMode)1 ObjectCache (com.jopdesign.wcet.jop.ObjectCache)1 FileNotFoundException (java.io.FileNotFoundException)1 PrintStream (java.io.PrintStream)1 ArrayList (java.util.ArrayList)1