int iCFThread = 0;
int iCFThreadInsignificantStart = setInsignificant.size();
CodeFragmentSet cfSet = threadDesc.getCodeFragmentSet();
double dblSumComputTime = 0;
double dblCurrentSkipTime = 0;
double dblSumIOCount = 0;
double dblSumIOSize = 0;
double dblCurrentIOCount = 0;
double dblCurrentIOSize = 0;
//Calculate the total CPU time, and I/O count and size for the thread
for (CodeFragmentDescriptor cf : cfSet.getCodeFragments())
{
iCFTotal++;
iCFThread++;
/*
* BUGBUG: this is temporarily, for testing only
*
*
if ((cf.getType() == CodeFragmentType.DISK_IO_OPEN)||
(cf.getType() == CodeFragmentType.DISK_IO_CLOSE))
{
setInsignificant.add(cf);
}
*/
if ((cf.getCodeFragmentType() == CodeFragmentType.THREAD_JOIN)||
(cf.getCodeFragmentType() == CodeFragmentType.THREAD_START)
)
{ //Treat thread start/join operations as unsignificant CFs
setInsignificant.add(cf);
}
if (isDiskDescriptorOp(cf) && m_bTreatDiskDescriptorOpsAsSignificant)
{ //This is a descriptor operation (file Open/Close),
//and we always treating those as significant operations
setInsignificant.add(cf);
continue;
}
if (cf.getCodeFragmentType() == CodeFragmentType.COMPUTATION)
{
dblSumComputTime += cf.getSumTime();
}
if (canCFCauseIO(cf))
{
if ((cf.getParameterValue(CodeFragmentParam.IO_COUNT) != null) ||
(cf.getParameterValue(CodeFragmentParam.IO_SIZE) != null))
{
dblSumIOCount += (Integer)cf.getParameterValue(CodeFragmentParam.IO_COUNT);
dblSumIOSize += (Integer)cf.getParameterValue(CodeFragmentParam.IO_SIZE);
}else
{ //This is an I/O CF that does not result in any I/O at all
//Ignore it
System.out.println(String.format("I/O CF %s is insignificant: spawns no I/O", cf));
setInsignificant.add(cf);
}
}
if ((cf.getCodeFragmentType() == CodeFragmentType.BARRIER_CREATE)||
(cf.getCodeFragmentType() == CodeFragmentType.BLOCKING_QUEUE_CREATE))
{ //Treat creation of synchronization operations as unsignificant CFs
setInsignificant.add(cf);
}
}
//Time threshold for this thread
double dblCPUThreshold = m_dblInsignificantThresholdComput * dblSumComputTime;
double dblIOCountThreshold = this.m_dblInsignificantThresholdIOCount * dblSumIOCount;
double dblIOSizeThreshold = this.m_dblInsignificantThresholdIOSize * dblSumIOSize;
//Pick CFs with minimum summary time one by one, until we either
//breach the threashold or pick all the available CFs
while (dblCurrentSkipTime < dblCPUThreshold)
{
double dblMinSumTime = Double.MAX_VALUE;
CodeFragmentDescriptor cfFound = null;
for (CodeFragmentDescriptor cf : cfSet.getCodeFragments())
{
if (setInsignificant.contains(cf))
{
continue;
}
if (cf.getCodeFragmentType() == CodeFragmentType.COMPUTATION)
{
if (cf.getSumTime() < dblMinSumTime)
{
dblMinSumTime = cf.getSumTime();
cfFound = cf;
}
}
}
if (cfFound == null)
{ //We can't find insignificant CFs any more
break;
}
if ((dblCurrentSkipTime + cfFound.getSumTime()) <= dblCPUThreshold)
{ //Found insignificant CF
System.out.println(String.format("Computational CF %s is insignificant: time %f, current skiptime %f, threshold %f",
cfFound, cfFound.getSumTime(), dblCurrentSkipTime, dblCPUThreshold));
setInsignificant.add(cfFound);
dblCurrentSkipTime += cfFound.getSumTime();
} else
{
break;
}
}
//Pick CFs with minimum summary time one by one, until we either
//breach the threashold or pick all the available CFs
while ((dblCurrentIOCount < dblIOCountThreshold) &&
(dblCurrentIOSize < dblIOSizeThreshold))
{
double dblMinIOScore = Double.MAX_VALUE;
CodeFragmentDescriptor cfFound = null;
for (CodeFragmentDescriptor cf : cfSet.getCodeFragments())
{
if (setInsignificant.contains(cf))
{
continue;
}
if (canCFCauseIO(cf))
{
Integer intIOCount = (Integer) cf.getParameterValue(CodeFragmentParam.IO_COUNT);
Integer intIOSize = (Integer)cf.getParameterValue(CodeFragmentParam.IO_SIZE);
if (intIOCount == 0)
{
throw new RampException(String.format("Number of I/O operations is 0 for the CF %s, thread %d",
cf.getName(), threadDesc.m_iID));
}
if (intIOSize == 0)
{
throw new RampException(String.format("Summary I/O size is 0 for the CF %s, thread %d",
cf.getName(), threadDesc.m_iID));
}
double dblIOScore = ((double)intIOCount)/dblSumIOCount+
((double)intIOSize)/dblSumIOSize;
//double dblIOScore = ((double) intIOCount)*dblIOCountScaleCoef +
// ((double) intIOSize)*dblIOSizeScaleCoef;
if (cf.getSumTime() < dblMinIOScore)
{
dblMinIOScore = dblIOScore;
cfFound = cf;
}
}
}
if (cfFound == null)
{ //We can't find insignificant CFs any more
break;
}
if (
((dblCurrentIOCount + (Integer)cfFound.getParameterValue(CodeFragmentParam.IO_COUNT)) <= dblIOCountThreshold) &&
((dblCurrentIOSize + (Integer)cfFound.getParameterValue(CodeFragmentParam.IO_SIZE)) <= dblIOSizeThreshold)
)
{ //Found insignificant CF
System.out.println(String.format("I/O CF %s is insignificant: I/O size %d, I/O count %d, current skip size %f, skip time %f, size threshold %f, time threshold %f",
cfFound,
(Integer)cfFound.getParameterValue(CodeFragmentParam.IO_SIZE),
(Integer)cfFound.getParameterValue(CodeFragmentParam.IO_COUNT),
dblCurrentIOSize,
dblCurrentIOCount,
dblIOSizeThreshold,
dblIOCountThreshold));
setInsignificant.add(cfFound);
dblCurrentIOCount += (Integer)cfFound.getParameterValue(CodeFragmentParam.IO_COUNT);
dblCurrentIOSize += (Integer)cfFound.getParameterValue(CodeFragmentParam.IO_SIZE);
} else
{
break;
}
}
//Also skip those code fragments whose mean time is less than threshold
for (CodeFragmentDescriptor cf : cfSet.getCodeFragments())
{
if (cf.getCodeFragmentType() != CodeFragmentType.COMPUTATION)
{
continue;
}
if (setInsignificant.contains(cf))
{
continue;
}
if (cf.getSumTime() / cf.getHits() < dblMinMeanTimeComput)
{
setInsignificant.add(cf);
}
}
//Skip sync. CFs that are either volatile locks or that refer to uncontended locks
//TODO: treat uncontended CFs as computation CFs?
for (CodeFragmentDescriptor cf : cfSet.getCodeFragments())
{
if (ProbeDescriptor.isSyncOperation(cf.getCodeFragmentType()))
{
Set<RampLock> setLocksUsed = m_lockSet.getLocksUsedByCF(cf.getName());
if (setLocksUsed.size() > 1)