From: <mar...@us...> - 2008-03-31 00:27:18
|
Revision: 166 http://gridsim.svn.sourceforge.net/gridsim/?rev=166&view=rev Author: marcos_dias Date: 2008-03-30 17:27:24 -0700 (Sun, 30 Mar 2008) Log Message: ----------- This update contains small updates in the policies such as improvement in the descriptions. Modified Paths: -------------- branches/gridsim4.0-branch3/examples/examples/ar/ARTest.java branches/gridsim4.0-branch3/examples/examples/ar/SimpleARExample01.java branches/gridsim4.0-branch3/examples/examples/workload/ar/TurboARCBMultipleQueuesExample01.java branches/gridsim4.0-branch3/examples/examples/workload/ar/TurboAREBMultipleQueuesExample01.java branches/gridsim4.0-branch3/examples/examples/workload/ar/TurboARExample01.java branches/gridsim4.0-branch3/examples/examples/workload/ar/TurboARExample02.java branches/gridsim4.0-branch3/examples/examples/workload/ar/TurboARExample03.java branches/gridsim4.0-branch3/examples/examples/workload/ar/TurboARExampleWithCancellation01.java branches/gridsim4.0-branch3/examples/examples/workload/parallel/TurboExample01.java branches/gridsim4.0-branch3/examples/examples/workload/parallel/TurboExampleCBMultiQueues02.java branches/gridsim4.0-branch3/examples/examples/workload/parallel/TurboExampleEBMultiQueues01.java branches/gridsim4.0-branch3/examples/examples/workload/parallel/TurboExampleEBMultiQueues02.java branches/gridsim4.0-branch3/examples/examples/workload/parallel/TurboExampleEasy01.java branches/gridsim4.0-branch3/examples/examples/workload/parallel/TurboExampleWithCancellation01.java branches/gridsim4.0-branch3/source/gridsim/turbo/AvailabilityProfile.java branches/gridsim4.0-branch3/source/gridsim/turbo/AvailabilityProfileEntry.java branches/gridsim4.0-branch3/source/gridsim/turbo/CBParallelSpaceShared.java branches/gridsim4.0-branch3/source/gridsim/turbo/EBParallelSpaceShared.java branches/gridsim4.0-branch3/source/gridsim/turbo/MPProfileEntry.java branches/gridsim4.0-branch3/source/gridsim/turbo/PERange.java branches/gridsim4.0-branch3/source/gridsim/turbo/PERangeList.java branches/gridsim4.0-branch3/source/gridsim/turbo/QueuePartition.java branches/gridsim4.0-branch3/source/gridsim/turbo/ScheduleItem.java Modified: branches/gridsim4.0-branch3/examples/examples/ar/ARTest.java =================================================================== --- branches/gridsim4.0-branch3/examples/examples/ar/ARTest.java 2008-03-30 03:49:36 UTC (rev 165) +++ branches/gridsim4.0-branch3/examples/examples/ar/ARTest.java 2008-03-31 00:27:24 UTC (rev 166) @@ -1,9 +1,10 @@ /* * Author Marcos Dias de Assuncao * Date: September 2007 + * * Description: A simple program to demonstrate of how to use basic - * advanced reservation functionalities, such as create, commit - * and status. + * advanced reservation functionalities, such as create, commit, + * get status of advance reservations and submit gridlets. */ package examples.ar; Modified: branches/gridsim4.0-branch3/examples/examples/ar/SimpleARExample01.java =================================================================== --- branches/gridsim4.0-branch3/examples/examples/ar/SimpleARExample01.java 2008-03-30 03:49:36 UTC (rev 165) +++ branches/gridsim4.0-branch3/examples/examples/ar/SimpleARExample01.java 2008-03-31 00:27:24 UTC (rev 166) @@ -1,9 +1,10 @@ /* * Author: Marcos Dias de Assuncao * Date: September 2007 + * * Description: A simple program to demonstrate of how to use basic - * advanced reservation functionalities, such as create, commit - * and status. + * advanced reservation functionalities, such as create, commit, + * get status of advance reservations and submit gridlets. */ package examples.ar; Modified: branches/gridsim4.0-branch3/examples/examples/workload/ar/TurboARCBMultipleQueuesExample01.java =================================================================== --- branches/gridsim4.0-branch3/examples/examples/workload/ar/TurboARCBMultipleQueuesExample01.java 2008-03-30 03:49:36 UTC (rev 165) +++ branches/gridsim4.0-branch3/examples/examples/workload/ar/TurboARCBMultipleQueuesExample01.java 2008-03-31 00:27:24 UTC (rev 166) @@ -2,7 +2,7 @@ * Author Marcos Dias de Assuncao * Date: February 2008 * - * Description: This example shows how to create a resource with a conservative + * Description: This example shows how to create a resource using a conservative * backfilling policy with advance reservation features and with multiple * partitions. The jobs are read from a trace file. To test this example, * you can use one of the traces included in the workloads directory. Modified: branches/gridsim4.0-branch3/examples/examples/workload/ar/TurboAREBMultipleQueuesExample01.java =================================================================== --- branches/gridsim4.0-branch3/examples/examples/workload/ar/TurboAREBMultipleQueuesExample01.java 2008-03-30 03:49:36 UTC (rev 165) +++ branches/gridsim4.0-branch3/examples/examples/workload/ar/TurboAREBMultipleQueuesExample01.java 2008-03-31 00:27:24 UTC (rev 166) @@ -1,3 +1,12 @@ +/* + * Author Marcos Dias de Assuncao + * Date: February 2008 + * + * Description: This example shows how to create a resource using an aggressive + * backfilling policy with advance reservation features and with multiple + * partitions. The jobs are read from a trace file. To test this example, + * you can use one of the traces included in the workloads directory. + */ package examples.workload.ar; Modified: branches/gridsim4.0-branch3/examples/examples/workload/ar/TurboARExample01.java =================================================================== --- branches/gridsim4.0-branch3/examples/examples/workload/ar/TurboARExample01.java 2008-03-30 03:49:36 UTC (rev 165) +++ branches/gridsim4.0-branch3/examples/examples/workload/ar/TurboARExample01.java 2008-03-31 00:27:24 UTC (rev 166) @@ -2,12 +2,12 @@ * Author Marcos Dias de Assuncao * Date: September 2007 * - * Description: This example shows how to create a resource with a + * Description: This example shows how to create a resource using a * conservative backfilling policy with advance reservation features. The jobs are * read from a trace file. To test this example, you can use one of the traces * included in the workloads directory. The jobs generated by this class are not * advance reservations, however. This example has been created for debugging - * purposes. + * purposes in order to test the normal job scheduling by the policy. */ package examples.workload.ar; Modified: branches/gridsim4.0-branch3/examples/examples/workload/ar/TurboARExample02.java =================================================================== --- branches/gridsim4.0-branch3/examples/examples/workload/ar/TurboARExample02.java 2008-03-30 03:49:36 UTC (rev 165) +++ branches/gridsim4.0-branch3/examples/examples/workload/ar/TurboARExample02.java 2008-03-31 00:27:24 UTC (rev 166) @@ -2,7 +2,7 @@ * Author Marcos Dias de Assuncao * Date: September 2007 * - * Description: This example shows how to create a resource with a + * Description: This example shows how to create a resource using a * conservative backfilling policy with advance reservation features. The jobs are * read from a trace file. To test this example, you can use one of the traces * included in the workloads directory. Modified: branches/gridsim4.0-branch3/examples/examples/workload/ar/TurboARExample03.java =================================================================== --- branches/gridsim4.0-branch3/examples/examples/workload/ar/TurboARExample03.java 2008-03-30 03:49:36 UTC (rev 165) +++ branches/gridsim4.0-branch3/examples/examples/workload/ar/TurboARExample03.java 2008-03-31 00:27:24 UTC (rev 166) @@ -5,8 +5,8 @@ * Description: This example creates three resources and three workload * objects. The workloads make advance reservations and submit gridlets * to the resources. The policy used by the resources is conservative - * backfilling with advance reservation. To test this example, you can use - * one of the traces included in the workloads directory. + * backfilling with advance reservation features. To test this example, + * you can use one of the traces included in the workloads directory. */ package examples.workload.ar; Modified: branches/gridsim4.0-branch3/examples/examples/workload/ar/TurboARExampleWithCancellation01.java =================================================================== --- branches/gridsim4.0-branch3/examples/examples/workload/ar/TurboARExampleWithCancellation01.java 2008-03-30 03:49:36 UTC (rev 165) +++ branches/gridsim4.0-branch3/examples/examples/workload/ar/TurboARExampleWithCancellation01.java 2008-03-31 00:27:24 UTC (rev 166) @@ -2,7 +2,7 @@ * Author Marcos Dias de Assuncao * Date: September 2007 * - * Description: This example shows how to create a resource with a + * Description: This example shows how to create a resource using a * conservative backfilling policy with advance reservation features. The jobs are * read from a trace file. The workload object cancels some of the gridlets * submitted to the resource. This example has been implemented to test Modified: branches/gridsim4.0-branch3/examples/examples/workload/parallel/TurboExample01.java =================================================================== --- branches/gridsim4.0-branch3/examples/examples/workload/parallel/TurboExample01.java 2008-03-30 03:49:36 UTC (rev 165) +++ branches/gridsim4.0-branch3/examples/examples/workload/parallel/TurboExample01.java 2008-03-31 00:27:24 UTC (rev 166) @@ -2,8 +2,8 @@ * Author Marcos Dias de Assuncao * Date: September 2007 * - * Description: This example shows how to create a resource with a - * conservative backfilling policy without advance reservation features. The jobs are + * Description: This example shows how to create a resource using a conservative + * backfilling policy without advance reservation features. The jobs are * read from a trace file. To test this example, you can use one of the traces * included in the workloads directory. */ Modified: branches/gridsim4.0-branch3/examples/examples/workload/parallel/TurboExampleCBMultiQueues02.java =================================================================== --- branches/gridsim4.0-branch3/examples/examples/workload/parallel/TurboExampleCBMultiQueues02.java 2008-03-30 03:49:36 UTC (rev 165) +++ branches/gridsim4.0-branch3/examples/examples/workload/parallel/TurboExampleCBMultiQueues02.java 2008-03-31 00:27:24 UTC (rev 166) @@ -2,7 +2,7 @@ * Author Marcos Dias de Assuncao * Date: February 2008 * - * Description: This example shows how to create a resource with a conservative + * Description: This example shows how to create a resource using a conservative * backfilling policy without advance reservation features but with multiple * partitions. The jobs are read from a trace file. To test this example, * you can use one of the traces included in the workloads directory. Modified: branches/gridsim4.0-branch3/examples/examples/workload/parallel/TurboExampleEBMultiQueues01.java =================================================================== --- branches/gridsim4.0-branch3/examples/examples/workload/parallel/TurboExampleEBMultiQueues01.java 2008-03-30 03:49:36 UTC (rev 165) +++ branches/gridsim4.0-branch3/examples/examples/workload/parallel/TurboExampleEBMultiQueues01.java 2008-03-31 00:27:24 UTC (rev 166) @@ -2,7 +2,7 @@ * Author Marcos Dias de Assuncao * Date: February 2008 * - * Description: This example shows how to create a resource with an aggressive + * Description: This example shows how to create a resource using an aggressive * backfilling policy without advance reservation features but with multiple * partitions. This example creates the policy with only one partition, however. * This has been done for debugging purposes. The policy should behave like a Modified: branches/gridsim4.0-branch3/examples/examples/workload/parallel/TurboExampleEBMultiQueues02.java =================================================================== --- branches/gridsim4.0-branch3/examples/examples/workload/parallel/TurboExampleEBMultiQueues02.java 2008-03-30 03:49:36 UTC (rev 165) +++ branches/gridsim4.0-branch3/examples/examples/workload/parallel/TurboExampleEBMultiQueues02.java 2008-03-31 00:27:24 UTC (rev 166) @@ -2,7 +2,7 @@ * Author Marcos Dias de Assuncao * Date: February 2008 * - * Description: This example shows how to create a resource with an aggressive + * Description: This example shows how to create a resource using an aggressive * backfilling policy without advance reservation features but with multiple * partitions. The jobs are read from a trace file. To test this example, * you can use one of the traces included in the workloads directory. Modified: branches/gridsim4.0-branch3/examples/examples/workload/parallel/TurboExampleEasy01.java =================================================================== --- branches/gridsim4.0-branch3/examples/examples/workload/parallel/TurboExampleEasy01.java 2008-03-30 03:49:36 UTC (rev 165) +++ branches/gridsim4.0-branch3/examples/examples/workload/parallel/TurboExampleEasy01.java 2008-03-31 00:27:24 UTC (rev 166) @@ -2,7 +2,7 @@ * Author Marcos Dias de Assuncao * Date: February 2008 * - * Description: This example shows how to create a resource with an aggressive + * Description: This example shows how to create a resource using an aggressive * backfilling policy without advance reservation features. The jobs are * read from a trace file. To test this example, you can use one of the traces * included in the workloads directory. Modified: branches/gridsim4.0-branch3/examples/examples/workload/parallel/TurboExampleWithCancellation01.java =================================================================== --- branches/gridsim4.0-branch3/examples/examples/workload/parallel/TurboExampleWithCancellation01.java 2008-03-30 03:49:36 UTC (rev 165) +++ branches/gridsim4.0-branch3/examples/examples/workload/parallel/TurboExampleWithCancellation01.java 2008-03-31 00:27:24 UTC (rev 166) @@ -2,7 +2,7 @@ * Author Marcos Dias de Assuncao * Date: September 2007 * - * Description: This example shows how to create a resource with a + * Description: This example shows how to create a resource using a * conservative backfilling policy without advance reservation features. * This example has beenn implemented to test the job cancellation. The workload * object created in this example cancels some of the gridlets submitted. The Modified: branches/gridsim4.0-branch3/source/gridsim/turbo/AvailabilityProfile.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/turbo/AvailabilityProfile.java 2008-03-30 03:49:36 UTC (rev 165) +++ branches/gridsim4.0-branch3/source/gridsim/turbo/AvailabilityProfile.java 2008-03-31 00:27:24 UTC (rev 166) @@ -19,7 +19,8 @@ * @since GridSim Turbo Alpha 0.1 */ -public class AvailabilityProfile extends ArrayList<AvailabilityProfileEntry> { +public class AvailabilityProfile extends ArrayList<AvailabilityProfileEntry> + implements Cloneable { private static final long serialVersionUID = -1853610061073508770L; @@ -31,7 +32,7 @@ } /** - * Returns a clone of this object.<br> + * Returns shallow copy of this object.<br> * <b>NOTE:</b> this method does not clone the entries * @return the cloned object */ @@ -44,6 +45,19 @@ } /** + * Returns copy of this object.<br> + * <b>NOTE:</b> this method clones the entries + * @return the copy object + */ + public AvailabilityProfile copy() { + AvailabilityProfile copy = new AvailabilityProfile(); + for(AvailabilityProfileEntry entry : this){ + copy.add(entry.clone()); + } + return copy; + } + + /** * Returns the entry whose time is closest to the <tt>time</tt> given but * smaller, or whose time is equals to <tt>time</tt> * @param time the time to be used to search for the entry Modified: branches/gridsim4.0-branch3/source/gridsim/turbo/AvailabilityProfileEntry.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/turbo/AvailabilityProfileEntry.java 2008-03-30 03:49:36 UTC (rev 165) +++ branches/gridsim4.0-branch3/source/gridsim/turbo/AvailabilityProfileEntry.java 2008-03-31 00:27:24 UTC (rev 166) @@ -15,7 +15,7 @@ * @since GridSim Turbo Alpha 0.1 */ -public class AvailabilityProfileEntry { +public class AvailabilityProfileEntry implements Cloneable { private PERangeList ranges_; // the ranges available private double time_; // the time when the ranges will be available @@ -25,16 +25,26 @@ * Creates an instance of @link{ProfileEntry}. * @param time the time associated with this event */ - public AvailabilityProfileEntry(double time){ + public AvailabilityProfileEntry(double time) { time_ = time; ranges_ = new PERangeList(); } /** + * Creates an instance of @link{ProfileEntry}. + * @param time the time associated with this event + * @param ranges the ranges to be used by this entry + */ + public AvailabilityProfileEntry(double time, PERangeList ranges) { + time_ = time; + ranges_ = ranges; + } + + /** * Returns the ranges of free PEs associated with this entry * @return the ranges of free PEs associated with this entry */ - public PERangeList getPERanges(){ + public PERangeList getPERanges() { return ranges_; } @@ -42,14 +52,14 @@ * Adds a range of PEs to the list * @param list the range of PEs */ - public void setPERangeList(PERangeList list){ + public void setPERangeList(PERangeList list) { ranges_ = list; } /** * Clears the list of PE ranges */ - public void clearPERangeList(){ + public void clearPERangeList() { ranges_.clear(); } @@ -57,7 +67,7 @@ * Returns the time associated with this entry * @return the time associated */ - public double getTime(){ + public double getTime() { return time_; } @@ -65,7 +75,7 @@ * Gets the number of PEs associated with this entry * @return the number of PEs */ - public int getNumPE(){ + public int getNumPE() { if(ranges_ == null) return 0; else @@ -76,7 +86,7 @@ * Sets the time associated with this event * @param time the time to be set */ - public void setTime(double time){ + public void setTime(double time) { time_ = time; } @@ -84,7 +94,7 @@ * Increases the number of Gridlets that rely on this entry to mark * their expected completion time or their anchor point */ - public void increaseGridlet(){ + public void increaseGridlet() { numGridlets_++; } @@ -92,7 +102,7 @@ * Decreases the number of Gridlets that rely on this entry to mark * their expected completion time or their anchor point */ - public void decreaseGridlet(){ + public void decreaseGridlet() { numGridlets_--; } @@ -101,14 +111,26 @@ * their expected completion time or their anchor point * @return the number of Gridlets that use this entry */ - public int getNumGridlets(){ + public int getNumGridlets() { return numGridlets_; } /** + * Returns a clone of this object. + * @return a clone of this object. + */ + public AvailabilityProfileEntry clone() { + PERangeList ranges = ranges_ == null ? null : ranges_.clone(); + AvailabilityProfileEntry entry = + new AvailabilityProfileEntry(time_, ranges); + entry.numGridlets_ = numGridlets_; + return entry; + } + + /** * Creates a string representation of this entry */ - public String toString(){ + public String toString() { return "ProfileEntry={time="+ time_ + "; gridlets=" + numGridlets_ + "; " + ( (ranges_!=null) ? ranges_ : "{[]}") + "}"; } Modified: branches/gridsim4.0-branch3/source/gridsim/turbo/CBParallelSpaceShared.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/turbo/CBParallelSpaceShared.java 2008-03-30 03:49:36 UTC (rev 165) +++ branches/gridsim4.0-branch3/source/gridsim/turbo/CBParallelSpaceShared.java 2008-03-31 00:27:24 UTC (rev 166) @@ -17,6 +17,7 @@ import java.util.Calendar; import java.util.Collections; +import java.util.Comparator; import java.util.Iterator; import java.util.LinkedList; @@ -113,8 +114,8 @@ // The rating of one PE protected int ratingPE_; - // to order gridlets by potential start time - private OrderGridletByStartTime orderStartTime_; + // heuristic used to order the jobs for backfilling + protected Comparator<SSGridlet> jobOrderHeuristic_; // the last time when the schedule updated was called private double lastScheduleUpdate_; @@ -150,7 +151,7 @@ runningGridlets_ = new LinkedList<SSGridlet>(); queuedGridlets_ = new LinkedList<SSGridlet>(); availProfile_ = new AvailabilityProfile(); - orderStartTime_ = new OrderGridletByStartTime(); + jobOrderHeuristic_ = null; lastScheduleUpdate_ = 0.0D; ratingPE_ = 0; } @@ -203,6 +204,22 @@ } /** + * Sets the heuristic used to order the jobs considered for backfilling + * or when a cancellation takes place + * @param comparator a comparator implementation that defines + * how gridlets are ordered. + * @return <tt>true</tt> if the heuristic was set correctly; + * <tt>false</tt> otherwise. + */ + public boolean setJobOrderingHeuristic(Comparator<SSGridlet> comparator) { + if(comparator == null) + return false; + + jobOrderHeuristic_ = comparator; + return true; + } + + /** * Schedules a new <tt>Gridlet</tt> received by the * <tt>GridResource</tt> entity. * @param gridlet a Gridlet object to be executed @@ -330,7 +347,7 @@ * back to sender, i.e. the <tt>userId</tt>. * * <li> If a Gridlet cannot be found in either execution and - * paused list, then a <tt>null</tt> Gridlet will be send back + * waiting lists, then a <tt>null</tt> Gridlet will be send back * to sender, i.e. the <tt>userId</tt>. * * <li> Once a Gridlet is cancelled, the availability profile @@ -402,6 +419,10 @@ null, gridletId, userId); return; } + + // check whether the Gridlet is running + boolean isRunning = sgl.getStatus() == Gridlet.INEXEC; + sgl.setStatus(Gridlet.CANCELED); //----------------- USED FOR DEBUGGING PURPOSES ONLY ------------------- @@ -411,7 +432,7 @@ //---------------------------------------------------------------------- // remove/update entries of the gridlet in the profile - removeGridlet(sgl); + removeGridlet(isRunning, sgl); // compress the schedule, that is, moves the gridlets forwards if(!sgl.hasReserved()) @@ -425,7 +446,6 @@ //---------------------------------------------------------------------- // sends the Gridlet back to user - sgl.setStatus(Gridlet.CANCELED); sgl.finalizeGridlet(); super.sendCancelGridlet(GridSimTags.GRIDLET_CANCEL, sgl.getGridlet(), gridletId, userId); @@ -511,7 +531,8 @@ // iterates the waiting queue and for each gridlet, put the ranges // used back in the profile. That is, updates the entries - Collections.sort(queuedGridlets_, orderStartTime_); + if(jobOrderHeuristic_ != null) + Collections.sort(queuedGridlets_, jobOrderHeuristic_); Iterator<SSGridlet> iterQueue = queuedGridlets_.iterator(); while(iterQueue.hasNext()) { @@ -1206,15 +1227,15 @@ /** * This method removes/updates all the entries of a gridlet from the profile * and updates the ranges of current free PEs if the gridlet was in execution. + * @param wasRunning <tt>true</tt> if the gridlet was running; + * <tt>false</tt> otherwise. * @param gridlet the Gridlet to be removed */ - private void removeGridlet(SSGridlet gridlet) { + private void removeGridlet(boolean wasRunning, SSGridlet gridlet) { if(!gridlet.hasReserved()) { - // check whether the Gridlet is running - boolean isRunning = gridlet.getStatus() == Gridlet.INEXEC; // removes the gridlet from the profile - updateEntriesAtProfile(isRunning, gridlet); + updateEntriesAtProfile(wasRunning, gridlet); } } } Modified: branches/gridsim4.0-branch3/source/gridsim/turbo/EBParallelSpaceShared.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/turbo/EBParallelSpaceShared.java 2008-03-30 03:49:36 UTC (rev 165) +++ branches/gridsim4.0-branch3/source/gridsim/turbo/EBParallelSpaceShared.java 2008-03-31 00:27:24 UTC (rev 166) @@ -16,7 +16,6 @@ import java.util.Calendar; import java.util.Collections; -import java.util.Comparator; import java.util.Iterator; import java.util.LinkedList; @@ -74,9 +73,6 @@ // Pivot jobs (i.e. the first n jobs in the queue) protected LinkedList<SSGridlet> pivotGridlets_; - - // heuristic used to order the jobs for backfilling - protected Comparator<SSGridlet> jobOrderHeuristic_; // Similarly to the aggressive backfilling in MAUI, the user // can specify how many pivots can be considered when scheduling a job. @@ -110,7 +106,6 @@ super(resourceName, entityName); // initialises local variables pivotGridlets_ = new LinkedList<SSGridlet>(); - jobOrderHeuristic_ = null; maxPivots_ = 1; // default number of pivots is one } @@ -155,21 +150,6 @@ } /** - * Sets the heuristic used to order the jobs considered for backfilling - * @param comparator a comparator implementation that defines - * how gridlets are ordered. - * @return <tt>true</tt> if the heuristic was set correctly; - * <tt>false</tt> otherwise. - */ - public boolean setJobOrderingHeuristic(Comparator<SSGridlet> comparator) { - if(comparator == null) - return false; - - jobOrderHeuristic_ = comparator; - return true; - } - - /** * Sets the maximum number of pivot jobs. Similarly to the aggressive * backfilling in MAUI, the system administrator can specify how many * pivots can be considered when scheduling a job. That is, a job can @@ -240,17 +220,124 @@ } } - /** - * Cancels a Gridlet running or in the waiting queue.<br> - * <b>NOTE: Not implemented YET.</b> + /** + * Cancels a Gridlet running or in the waiting queue. + * This method will search the running and waiting queues. + * The User ID is important as many users might have the same + * Gridlet ID in the lists. If a Gridlet is cancelled and the gridlet was + * either running or was a pivot, then the availability profile is updated. + * After that, the backfilling algorithm is called to check which + * gridlets can be started or scheduled. + * <b>NOTE:</b> + * <ul> + * <li> Before cancelling a Gridlet, this method updates when + * the expected completion time of the Gridlet is. If the + * completion time is smaller than the current time, then + * the Gridlet is considered to be <tt>finished</tt>. + * Therefore the Gridlet cannot be cancelled. + * + * <li> Once a Gridlet has been cancelled, it cannot be resumed + * to execute again since this method will pass the Gridlet + * back to sender, i.e. the <tt>userId</tt>. + * + * <li> If a Gridlet cannot be found in either execution and + * waiting lists, then a <tt>null</tt> Gridlet will be send back + * to sender, i.e. the <tt>userId</tt>. + * </ul> * @param gridletId a Gridlet ID * @param userId the user or owner's ID of this Gridlet * @pre gridletId > 0 * @pre userId > 0 */ public void gridletCancel(int gridletId, int userId) { - System.out.println(super.get_name() + - ".gridletCancel(): not supported at the moment."); + double currentTime = GridSim.clock(); + + // stores the gridlet if found + SSGridlet sgl = null; + boolean found = false; + boolean updateProfile = false; + + // Look for the Gridlet in the running queue + sgl = findSSGridlet(runningGridlets_, gridletId, userId); + if (sgl != null) { + found = true; + + // if the Gridlet's finish time is smaller than the current + // time or the status is FINISHED, it means that the Gridlet + // has finished, but has not been removed from the running + // queue yet. It will probably be done shortly, + // so just send a null to the user. + if(sgl.getStatus() == Gridlet.SUCCESS || + sgl.getActualFinishTime() <= currentTime){ + super.sendCancelGridlet(GridSimTags.GRIDLET_CANCEL, + null, gridletId, userId); + return; // return as it is impossible to cancel the Gridlet + } + else{ + // remove from the queue before compressing the schedule + runningGridlets_.remove(sgl); + updateProfile = true; + } + } + + if(!found) { + // Look for the gridlet in the waiting queue + sgl = findSSGridlet(queuedGridlets_, gridletId, userId); + if (sgl != null) { + found = true; + + // Get the Gridlet from the waiting queue and + // remove from the queue before compressing the schedule + queuedGridlets_.remove(sgl); + + // if start time has been set, then it means that gridlet is + // a pivot. So, we need to remove it from the pivot list + if(sgl.getStartTime() > 0) { + pivotGridlets_.remove(sgl); + updateProfile = true; + } + } + } + + // If the Gridlet could not be found in neither queue, then send a null + // Gridlet to the user and return because there is no need to + // compress the schedule + if(!found) { + System.out.println(super.get_name() + ".gridletCancel():" + + " Cannot find Gridlet #" + gridletId + " for User #" + userId); + super.sendCancelGridlet(GridSimTags.GRIDLET_CANCEL, + null, gridletId, userId); + return; + } + + // check whether the Gridlet is running + boolean isRunning = sgl.getStatus() == Gridlet.INEXEC; + sgl.setStatus(Gridlet.CANCELED); + + //----------------- USED FOR DEBUGGING PURPOSES ONLY ------------------- + + // If a gridlet has been cancelled, then inform the listeners + GridSim.notifyListeners(this.get_id(), AllocationAction.ITEM_CANCELLED, true, sgl); + + //---------------------------------------------------------------------- + + // remove/update entries of the gridlet in the profile + if(updateProfile) { + removeGridlet(isRunning, sgl); + backfillGridlets(currentTime); + + //------------------- USED FOR DEBUGGING PURPOSES ONLY ----------------- + + // Inform the listeners about the new schedule + GridSim.notifyListeners(this.get_id(), AllocationAction.SCHEDULE_CHANGED, true); + + //---------------------------------------------------------------------- + } + + // sends the Gridlet back to user + sgl.finalizeGridlet(); + super.sendCancelGridlet(GridSimTags.GRIDLET_CANCEL, + sgl.getGridlet(), gridletId, userId); } /** @@ -393,8 +480,8 @@ // order jobs according to the ordering heuristic provided. // That is, if one was provided by the user. - if(jobOrderHeuristic_ != null) - Collections.sort(queuedGridlets_, jobOrderHeuristic_); + if(super.jobOrderHeuristic_ != null) + Collections.sort(queuedGridlets_, super.jobOrderHeuristic_); // Start the execution of Gridlets that are queued iter = queuedGridlets_.iterator(); @@ -427,4 +514,21 @@ return gridletStarted; } + + // ------------------------- PRIVATE METHODS ---------------------------- + + /** + * This method removes/updates all the entries of a gridlet from the profile + * and updates the ranges of current free PEs if the gridlet was in execution. + * @param wasRunning <tt>true</tt> if the gridlet was running; + * <tt>false</tt> otherwise. + * @param gridlet the Gridlet to be removed + */ + private void removeGridlet(boolean wasRunning, SSGridlet gridlet) { + if(!gridlet.hasReserved()) { + + // removes the gridlet from the profile + updateEntriesAtProfile(wasRunning, gridlet); + } + } } Modified: branches/gridsim4.0-branch3/source/gridsim/turbo/MPProfileEntry.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/turbo/MPProfileEntry.java 2008-03-30 03:49:36 UTC (rev 165) +++ branches/gridsim4.0-branch3/source/gridsim/turbo/MPProfileEntry.java 2008-03-31 00:27:24 UTC (rev 166) @@ -10,7 +10,7 @@ * @author Marcos Dias de Assuncao * @since GridSim Turbo Alpha 0.1 */ -public class MPProfileEntry { +public class MPProfileEntry implements Cloneable { // the ranges available private HashMap <Integer, PERangeList> ranges_; // the time when the ranges will be available Modified: branches/gridsim4.0-branch3/source/gridsim/turbo/PERange.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/turbo/PERange.java 2008-03-30 03:49:36 UTC (rev 165) +++ branches/gridsim4.0-branch3/source/gridsim/turbo/PERange.java 2008-03-31 00:27:24 UTC (rev 166) @@ -16,6 +16,7 @@ * @since GridSim Turbo Alpha 0.1 * @see PERangeList * @see CBParallelSpaceShared + * @see EBParallelSpaceShared */ public class PERange implements Cloneable, Comparable<PERange> { Modified: branches/gridsim4.0-branch3/source/gridsim/turbo/PERangeList.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/turbo/PERangeList.java 2008-03-30 03:49:36 UTC (rev 165) +++ branches/gridsim4.0-branch3/source/gridsim/turbo/PERangeList.java 2008-03-31 00:27:24 UTC (rev 166) @@ -22,6 +22,7 @@ * * @see PERange * @see CBParallelSpaceShared + * @see EBParallelSpaceShared * @see ARParallelSpaceShared */ Modified: branches/gridsim4.0-branch3/source/gridsim/turbo/QueuePartition.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/turbo/QueuePartition.java 2008-03-30 03:49:36 UTC (rev 165) +++ branches/gridsim4.0-branch3/source/gridsim/turbo/QueuePartition.java 2008-03-31 00:27:24 UTC (rev 166) @@ -15,7 +15,7 @@ private QueuePartitionPredicate predicate_; /** - * Creates a new <tt>Queuepartition</tt> object. + * Creates a new <tt>QueuePartition</tt> object. * @param queueId the partition ID * @param numPE the number of PEs initially assigned to the partition * @param predicate the queue predicate Modified: branches/gridsim4.0-branch3/source/gridsim/turbo/ScheduleItem.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/turbo/ScheduleItem.java 2008-03-30 03:49:36 UTC (rev 165) +++ branches/gridsim4.0-branch3/source/gridsim/turbo/ScheduleItem.java 2008-03-31 00:27:24 UTC (rev 166) @@ -23,6 +23,7 @@ * @see SSGridlet * @see Reservation * @see CBParallelSpaceShared + * @see EBParallelSpaceShared * @see ARParallelSpaceShared */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mar...@us...> - 2008-05-19 04:23:02
|
Revision: 174 http://gridsim.svn.sourceforge.net/gridsim/?rev=174&view=rev Author: marcos_dias Date: 2008-05-18 21:23:04 -0700 (Sun, 18 May 2008) Log Message: ----------- Small improvements in the allocation policies to allow the user to specify different forms to obtain alternative schedules for rejected advance reservations. Also, small changes in the Lublin 99 workload model have been made. Modified Paths: -------------- branches/gridsim4.0-branch3/examples/examples/workload/parallel/LublinWorkloadExample01.java branches/gridsim4.0-branch3/source/gridsim/turbo/ARCBMultiplePartitions.java branches/gridsim4.0-branch3/source/gridsim/turbo/AREBMultiplePartitions.java branches/gridsim4.0-branch3/source/gridsim/turbo/ARParallelSpaceShared.java branches/gridsim4.0-branch3/source/gridsim/turbo/Lublin99Workload.java branches/gridsim4.0-branch3/source/gridsim/turbo/MPAvailabilityProfile.java Added Paths: ----------- branches/gridsim4.0-branch3/source/gridsim/turbo/WorkloadInterface.java branches/gridsim4.0-branch3/source/gridsim/util/Workload.java Removed Paths: ------------- branches/gridsim4.0-branch3/source/gridsim/util/Workload.java Modified: branches/gridsim4.0-branch3/examples/examples/workload/parallel/LublinWorkloadExample01.java =================================================================== --- branches/gridsim4.0-branch3/examples/examples/workload/parallel/LublinWorkloadExample01.java 2008-05-11 00:55:20 UTC (rev 173) +++ branches/gridsim4.0-branch3/examples/examples/workload/parallel/LublinWorkloadExample01.java 2008-05-19 04:23:04 UTC (rev 174) @@ -95,9 +95,9 @@ double uHi = Math.log(totalPE * totalMachine) / Math.log(2d); double uMed = uHi-2.5; - workload.setParallelJobProbabilities(Lublin99Workload.BATCH_JOBS, - workload.getParallelJobULow(Lublin99Workload.BATCH_JOBS), uMed, uHi, - workload.getParallelJobUProb(Lublin99Workload.BATCH_JOBS)); + workload.setParallelJobProbabilities(Lublin99Workload.INTERACTIVE_JOBS, + workload.getParallelJobULow(Lublin99Workload.INTERACTIVE_JOBS), uMed, uHi, + workload.getParallelJobUProb(Lublin99Workload.INTERACTIVE_JOBS)); // sets the workload to create 1000 jobs workload.setNumJobs(1000); Modified: branches/gridsim4.0-branch3/source/gridsim/turbo/ARCBMultiplePartitions.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/turbo/ARCBMultiplePartitions.java 2008-05-11 00:55:20 UTC (rev 173) +++ branches/gridsim4.0-branch3/source/gridsim/turbo/ARCBMultiplePartitions.java 2008-05-19 04:23:04 UTC (rev 174) @@ -354,15 +354,18 @@ " PEs from " + startTime + " to " + sRes.getActualFinishTime()); System.out.println("--> The resource could not handle the reservation."); - // Gets availability information and provides it as options - AvailabilityInfo availability = super.allowBorrowing_ ? - getAvailabilityInfo(startTime, Integer.MAX_VALUE) : - getAvailabilityInfo(sRes.getPartitionID(), - startTime, Integer.MAX_VALUE); + // Gets availability information and provides it as options + AvailabilityInfo availability = getReservationAlternatives(sRes); + if(availability != null) { + reservation.setReservationOptions(availability); + response.setErrorCode(ARMessage.EC_OPERATION_FAILURE_BUT_OPTIONS); + } + else { + response.setErrorCode(ARMessage.EC_OPERATION_FAILURE); + } + reservation.setStatus(Reservation.STATUS_FAILED); - reservation.setReservationOptions(availability); - response.setErrorCode(ARMessage.EC_OPERATION_FAILURE_BUT_OPTIONS); sendARMessage(response); return false; } @@ -907,6 +910,30 @@ return list; } + + /** + * Gets the reservation alternatives to be provided to the reservation + * requester or user in case a given advance reservation is not accepted.<br> + * <b>NOTE:</b> The default implementation of this method returns the + * resource availability information to the user. To do so, the method + * queries the availability using the reservation's start time as start time + * for the query and {@link Integer.MAX_VALUE} as the duration in seconds. + * If the policy allows borrowing of resources, all the resources are considered; + * otherwise, only the resources available to the partition to which the + * reservation falls are provided. + * @param sRes the server side reservation for which alternatives are to be given + * @return an availability object containing the resource availability or + * <tt>null</tt> in case no options are to be provided. + */ + protected AvailabilityInfo getReservationAlternatives(SSReservation sRes) { + // Gets availability information and provides it as options + AvailabilityInfo availability = super.allowBorrowing_ ? + getAvailabilityInfo(sRes.getStartTime(), Integer.MAX_VALUE) : + getAvailabilityInfo(sRes.getPartitionID(), + sRes.getStartTime(), Integer.MAX_VALUE); + + return availability; + } /** * Sends a reservation message. Modified: branches/gridsim4.0-branch3/source/gridsim/turbo/AREBMultiplePartitions.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/turbo/AREBMultiplePartitions.java 2008-05-11 00:55:20 UTC (rev 173) +++ branches/gridsim4.0-branch3/source/gridsim/turbo/AREBMultiplePartitions.java 2008-05-19 04:23:04 UTC (rev 174) @@ -270,14 +270,14 @@ if (sRes.getStatus() == Reservation.STATUS_NOT_COMMITTED) { sRes.setStatus(Reservation.STATUS_COMMITTED); super.sendInternalEvent(resStartTime - currentTime, - CBParallelSpaceShared.UPDATE_SCHEDULE_TAG); + UPDATE_SCHEDULE_TAG); } // if the reservation has already started, then update the // schedule, which will force the gridlets in the queue to // be started else if(sRes.getStatus() == Reservation.STATUS_IN_PROGRESS) { super.sendInternalEvent(resStartTime - currentTime, - CBParallelSpaceShared.UPDATE_SCHEDULE_TAG); + UPDATE_SCHEDULE_TAG); } } @@ -362,15 +362,18 @@ " PEs from " + startTime + " to " + sRes.getActualFinishTime()); System.out.println("--> The resource could not handle the reservation."); - // Gets availability information and provides it as options - AvailabilityInfo availability = super.allowBorrowing_ ? - getAvailabilityInfo(startTime, Integer.MAX_VALUE) : - getAvailabilityInfo(sRes.getPartitionID(), - startTime, Integer.MAX_VALUE); - + // Gets availability information and provides it as options + AvailabilityInfo availability = getReservationAlternatives(sRes); + + if(availability != null) { + reservation.setReservationOptions(availability); + response.setErrorCode(ARMessage.EC_OPERATION_FAILURE_BUT_OPTIONS); + } + else { + response.setErrorCode(ARMessage.EC_OPERATION_FAILURE); + } + reservation.setStatus(Reservation.STATUS_FAILED); - reservation.setReservationOptions(availability); - response.setErrorCode(ARMessage.EC_OPERATION_FAILURE_BUT_OPTIONS); sendARMessage(response); return false; } @@ -388,7 +391,7 @@ if(currentTime == startTime) { sRes.setStatus(Reservation.STATUS_COMMITTED); super.sendInternalEvent(GridSimTags.SCHEDULE_NOW, - CBParallelSpaceShared.UPDATE_SCHEDULE_TAG); + UPDATE_SCHEDULE_TAG); } else { sRes.setStatus(Reservation.STATUS_NOT_COMMITTED); @@ -478,7 +481,7 @@ // then send this into itself to start the reservation super.sendInternalEvent(sRes.getStartTime() - GridSim.clock(), - CBParallelSpaceShared.UPDATE_SCHEDULE_TAG); + UPDATE_SCHEDULE_TAG); } // sends the response message with no error @@ -739,7 +742,7 @@ startedReservations.add(sRes); super.sendInternalEvent(sRes.getActualFinishTime()-refTime, - CBParallelSpaceShared.UPDATE_SCHEDULE_TAG); + UPDATE_SCHEDULE_TAG); numStartedRes++; } @@ -915,6 +918,30 @@ return list; } + + /** + * Gets the reservation alternatives to be provided to the reservation + * requester or user in case a given advance reservation is not accepted.<br> + * <b>NOTE:</b> The default implementation of this method returns the + * resource availability information to the user. To do so, the method + * queries the availability using the reservation's start time as start time + * for the query and {@link Integer.MAX_VALUE} as the duration in seconds. + * If the policy allows borrowing of resources, all the resources are considered; + * otherwise, only the resources available to the partition to which the + * reservation falls are provided. + * @param sRes the server side reservation for which alternatives are to be given + * @return an availability object containing the resource availability or + * <tt>null</tt> in case no options are to be provided. + */ + protected AvailabilityInfo getReservationAlternatives(SSReservation sRes) { + // Gets availability information and provides it as options + AvailabilityInfo availability = super.allowBorrowing_ ? + getAvailabilityInfo(sRes.getStartTime(), Integer.MAX_VALUE) : + getAvailabilityInfo(sRes.getPartitionID(), + sRes.getStartTime(), Integer.MAX_VALUE); + + return availability; + } /** * Sends a reservation message. @@ -927,7 +954,7 @@ message.getMessageSize(), message.getDestinationID())); } - // ------------------------- PRIVATE MTHODS ---------------------- + // ------------------------- PRIVATE METHODS ---------------------- /** * Checks for expiry time of a given reservations in the list. @@ -982,7 +1009,6 @@ // backfills Gridlets to fill the fragment created by the // cancellation of the advance reservation super.backfillGridlets(currentTime); -// super.compressSchedule(referenceTime, false); //---------------- USED FOR DEBUGGING PURPOSES ONLY ---------------- Modified: branches/gridsim4.0-branch3/source/gridsim/turbo/ARParallelSpaceShared.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/turbo/ARParallelSpaceShared.java 2008-05-11 00:55:20 UTC (rev 173) +++ branches/gridsim4.0-branch3/source/gridsim/turbo/ARParallelSpaceShared.java 2008-05-19 04:23:04 UTC (rev 174) @@ -205,39 +205,31 @@ // gets the reservation object and extract some // information from it Reservation reservation = message.getReservation(); - double startTime = reservation.getStartTime(); - int duration = reservation.getDurationTime(); - int reqPE = reservation.getNumPE(); // creates a Server Side Reservation (i.e. SSReservation) SSReservation sRes = new SSReservation(reservation); - double expTime = Double.NaN; - // creates a response message to be sent to the requester - ARMessage response = message.createResponse(); - //-------------- FOR DEBUGGING PURPOSES ONLY -------------- // informs the listeners that a reservation request has arrived GridSim.notifyListeners(this.get_id(), AllocationAction.ITEM_ARRIVED, true, sRes); //---------------------------------------------------------- - - if (reqPE > super.totalPE_) { - String userName = GridSim.getEntityName( message.getSourceID() ); - System.out.println(super.get_name() + ".handleCreateReservation():" + - " Reservation #" + reservation.getID() + " from " + - userName + " user requires " + reservation.getNumPE() + - " PEs from " + startTime + " to " + (startTime + duration)); - System.out.println("--> The resource has only " + - super.totalPE_ + " PEs available."); - + + // creates a response message to be sent to the requester + ARMessage response = message.createResponse(); + + if(!validateReservation(sRes)){ reservation.setStatus(Reservation.STATUS_FAILED); response.setErrorCode(ARMessage.EC_OPERATION_FAILURE); sendARMessage(response); - return false; - } - + return false; + } + + double startTime = reservation.getStartTime(); + int duration = reservation.getDurationTime(); + int reqPE = reservation.getNumPE(); + double expTime = Double.NaN; boolean success = true; // if start time is 0, then it is an immediate reservation @@ -373,14 +365,19 @@ //---------------------------------------------------------- } else { // Creates a list of options - + // Gets availability information and provides it as options - AvailabilityInfo availability = - getAvailabilityInfo(startTime, Integer.MAX_VALUE); + AvailabilityInfo availability = getReservationAlternatives(sRes); - reservation.setStatus(Reservation.STATUS_FAILED); - reservation.setReservationOptions(availability); - response.setErrorCode(ARMessage.EC_OPERATION_FAILURE_BUT_OPTIONS); + if(availability != null) { + reservation.setReservationOptions(availability); + response.setErrorCode(ARMessage.EC_OPERATION_FAILURE_BUT_OPTIONS); + } + else { + response.setErrorCode(ARMessage.EC_OPERATION_FAILURE); + } + + reservation.setStatus(Reservation.STATUS_FAILED); sendARMessage(response); return false; } @@ -1109,6 +1106,29 @@ // ---------------------- PROTECTED METHODS ------------------------ /** + * Checks whether the reservation can be handled by the resource. That is, + * verifies if it does not require more resources than what the resource + * can provide. + * @param res the server side reservation to be examined + * @return <tt>true</tt> if it can be handled; <tt>false</tt> otherwise. + */ + protected boolean validateReservation(SSReservation res) { + int reqPE = res.getNumPE(); + if (reqPE > super.totalPE_) { + String userName = GridSim.getEntityName( res.getSenderID() ); + System.out.println(super.get_name() + ".validateReservation():" + + " Reservation #" + res.getID() + " from " + + userName + " user requires " + reqPE + + " PEs from " + res.getStartTime() + " to " + res.getActualFinishTime()); + System.out.println("--> The resource has only " + + super.totalPE_ + " PEs available."); + return false; + } + + return true; + } + + /** * This method is called to update the schedule. It removes completed * gridlets and return them to the users and verifies whether there are * gridlets in the waiting list that should start execution. It also @@ -1233,6 +1253,22 @@ return list; } + /** + * Gets the reservation alternatives to be provided to the reservation + * requester or user in case a given advance reservation is not accepted.<br> + * <b>NOTE:</b> The default implementation of this method returns the + * resource availability information to the user. To do so, the method + * queries the availability using the reservation's start time as start time + * for the query and {@link Integer.MAX_VALUE} as the duration in seconds. + * @param sRes the server side reservation for which alternatives are to be given + * @return an availability object containing the resource availability or + * <tt>null</tt> in case no options are to be provided. + */ + protected AvailabilityInfo getReservationAlternatives(SSReservation sRes) { + // Gets availability information + return getAvailabilityInfo(sRes.getStartTime(), Integer.MAX_VALUE); + } + /** * Search for a particular reservation in a data structure * @param obj a data structure Modified: branches/gridsim4.0-branch3/source/gridsim/turbo/Lublin99Workload.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/turbo/Lublin99Workload.java 2008-05-11 00:55:20 UTC (rev 173) +++ branches/gridsim4.0-branch3/source/gridsim/turbo/Lublin99Workload.java 2008-05-19 04:23:04 UTC (rev 174) @@ -59,19 +59,21 @@ * @author Marcos Dias de Assuncao * @since GridSim Turbo Alpha 0.1 */ -public class Lublin99Workload extends GridSim { +public class Lublin99Workload extends + GridSim implements WorkloadInterface { private String resName_; // resource name private int resID_; // resource ID private int rating_; // a PE rating private int gridletID_; // gridletID private int size_; // job size for sending it through a network - private ArrayList<Gridlet> list_; // a list for getting all the Gridlets - private Random random_ = null; // the number generator to be used + private ArrayList<Gridlet> list_; // a list for getting all the Gridlets + private Random random_ = null; // the number generator to be used + private int gridletsReturned_; // starts at 1, since gridletID_ starts at 1 too + private long lastSubmissionTime_; // Log PI for log gamma method private static final double LOGPI = 1.14472988584940017414; - private final int INTERVAL = 10; // number of intervals private static final int UNKNOWN = -1; // ------------ CONSTANTS USED BY THE WORKLOAD MODEL -------------- @@ -182,7 +184,7 @@ /* * Here are the model's parameters for typeless data (no batch nor interactive) - * We use those parameters when INCLUDE_JOBS_TYPE is off (0) + * We use those parameters when useJobType_ is false */ private static final double SERIAL_PROB = 0.244; private static final double POW2_PROB = 0.576; @@ -437,6 +439,7 @@ private void init(String resourceName, int rating, boolean useJobType, long seed) { + lastSubmissionTime_ = -1; useJobType_ = useJobType; resName_ = resourceName; resID_ = GridSim.getEntityId(resName_); @@ -464,16 +467,16 @@ if (useJobType_) { serialProb[BATCH_JOBS] = SERIAL_PROB_BATCH; pow2Prob[BATCH_JOBS] = POW2_PROB_BATCH; - uLow[BATCH_JOBS] = ULOW_BATCH; - uMed[BATCH_JOBS] = UMED_BATCH; - uHi[BATCH_JOBS] = UHI_BATCH; + uLow[BATCH_JOBS] = ULOW_BATCH; + uMed[BATCH_JOBS] = UMED_BATCH; + uHi[BATCH_JOBS] = UHI_BATCH; uProb[BATCH_JOBS] = UPROB_BATCH; serialProb[INTERACTIVE_JOBS] = SERIAL_PROB_ACTIVE; pow2Prob[INTERACTIVE_JOBS] = POW2_PROB_ACTIVE; uLow[INTERACTIVE_JOBS] = ULOW_ACTIVE; uMed[INTERACTIVE_JOBS] = UMED_ACTIVE; - uHi[INTERACTIVE_JOBS] = UHI_ACTIVE; + uHi[INTERACTIVE_JOBS] = UHI_ACTIVE; uProb[INTERACTIVE_JOBS] = UPROB_ACTIVE; a1[BATCH_JOBS] = A1_BATCH; b1[BATCH_JOBS] = B1_BATCH; @@ -493,13 +496,13 @@ bnum[INTERACTIVE_JOBS] = BNUM_ACTIVE; } else { - // whole sample -- make all batch jobs + // whole sample -- make all interactive jobs serialProb[BATCH_JOBS] = serialProb[INTERACTIVE_JOBS] = SERIAL_PROB; pow2Prob[BATCH_JOBS] = pow2Prob[INTERACTIVE_JOBS] = POW2_PROB; - uLow[BATCH_JOBS] = uLow[INTERACTIVE_JOBS] = ULOW ; - uMed[BATCH_JOBS] = uMed[INTERACTIVE_JOBS] = UMED ; - uHi[BATCH_JOBS] = uHi[INTERACTIVE_JOBS] = UHI ; - uProb[BATCH_JOBS] = uProb[INTERACTIVE_JOBS] = UPROB ; + uLow[BATCH_JOBS] = uLow[INTERACTIVE_JOBS] = ULOW; + uMed[BATCH_JOBS] = uMed[INTERACTIVE_JOBS] = UMED; + uHi[BATCH_JOBS] = uHi[INTERACTIVE_JOBS] = UHI; + uProb[BATCH_JOBS] = uProb[INTERACTIVE_JOBS] = UPROB; a1[BATCH_JOBS] = a1[INTERACTIVE_JOBS] = A1; b1[BATCH_JOBS] = b1[INTERACTIVE_JOBS] = B1; @@ -514,8 +517,11 @@ bnum[BATCH_JOBS] = bnum[INTERACTIVE_JOBS] = BNUM; } - if ( ! useJobType_ ) // make all jobs batch - timeFromBegin_[INTERACTIVE_JOBS] = Long.MAX_VALUE; +// if ( ! useJobType_ ) // make all jobs batch +// timeFromBegin_[INTERACTIVE_JOBS] = Long.MAX_VALUE; + + if ( ! useJobType_ ) // make all jobs interactive + timeFromBegin_[BATCH_JOBS] = Long.MAX_VALUE; } /** @@ -820,7 +826,7 @@ * Sets the maximum number of jobs to be generated by this workload model * @param numJobs the number of jobs * @return <tt>true</tt> if the number of jobs has been set; - * <tt>false</tt> othwerwise. + * <tt>false</tt> otherwise. */ public boolean setNumJobs(int numJobs) { if(numJobs < 1) @@ -967,11 +973,12 @@ // if all the gridlets have been submitted if (success == true) { - collectGridlet(); + finishGridletSubmission(lastSubmissionTime_); + processEvents(); } else { System.out.println(super.get_name() + - ".body(): Error - unable to parse from a file."); + ".body(): Error - unable to create the gridlets."); } // shut down all the entities, including GridStatistics entity since @@ -986,45 +993,44 @@ //////////////////////// PROTECTED METHODS /////////////////////// /** - * Collects Gridlets sent and stores them into a list. - * @pre $none + * Processes events such as receiving of gridlets. * @post $none */ - protected void collectGridlet() { + protected void processEvents() { System.out.println(super.get_name() + ": Collecting Gridlets ..."); list_ = new ArrayList<Gridlet>(gridletID_ + 1); + gridletsReturned_ = 1; // starts at 1, since gridletID_ starts at 1 too Object data = null; Gridlet gl = null; - int counter = 1; // starts at 1, since gridletID_ starts at 1 too Sim_event ev = new Sim_event(); while ( Sim_system.running() ) { super.sim_get_next(ev); // get the next available event + + // get the Gridlet data data = ev.get_data(); // get the event's data // handle ping request - if (ev.get_tag() == GridSimTags.INFOPKT_SUBMIT) - { + if (ev.get_tag() == GridSimTags.INFOPKT_SUBMIT) { processPingRequest(ev); continue; } - - // get the Gridlet data - if (data != null && data instanceof Gridlet) { - gl = (Gridlet) data; - list_.add(gl); - counter++; + else if (data != null && data instanceof Gridlet) { + onGridletReceipt((Gridlet)data); } + else { + processOtherEvent(ev); + } // if all the Gridlets have been collected - if (counter == gridletID_) { + if (gridletsReturned_ == gridletID_) { break; } } } - + /** * Processes a ping request. * @param ev a Sim_event object @@ -1051,6 +1057,9 @@ * <tt>false</tt> otherwise. */ private boolean createGridlets() { + + System.out.println(super.get_name() + ": Submitting Gridlets to " + + resName_ + " ..."); int type = INTERACTIVE_JOBS; int nodes; long arrTime; int runTime; @@ -1072,12 +1081,58 @@ runTime = (int)timeFromNodes(a1[type], b1[type], a2[type], b2[type], pa[type], pb[type], nodes); - submitGridlet(i+1, arrTime, runTime, nodes); + onGridletCreation(i+1, arrTime, runTime, nodes); } return true; } + /** + * This method is called by the workload model once information for a + * gridlet is created by the model. + * @param gridletId the id assigned to the gridlet + * @param submitTime the time the gridlet should be submitted + * @param runTime the runtime estimate for the gridlet + * @param numProc the number of processors required by the gridlet + * @see gridsim.turbo.WorkloadInterface#onGridletCreation(int, long, int, int) + */ + public void onGridletCreation(int gridletId, long submitTime, + int runTime, int numProc) { + submitGridlet(gridletId, submitTime, runTime, numProc); + } + + /** + * Invoked by the workload implementation when an event could not + * be handled. + * @param ev the event to be handled. + */ + public void processOtherEvent(Sim_event ev) { + System.out.println(get_name() + ": could not handle event with tag " + + ev.get_tag()); + } + + /** + * This method is invoked by the workload reader/model upon the scheduling + * of the last gridlet created. This is useful in case the user wants to + * schedule an event to cancel the simulation at the submission of the last + * job to avoid the cool down phase of the simulation. + * @param lastSubmissionTime the time when the last gridlet + * submission took place + */ + public void finishGridletSubmission(double lastSubmissionTime) { + return; + } + + /** + * This method is invoked when a Gridlet is returned by the resource + * back to a workload model or trace reader. + * @param grl the gridlet returned by the resource + */ + public void onGridletReceipt(Gridlet grl) { + list_.add(grl); + gridletsReturned_++; + } + /* * We distinguish between serial jobs , power2 jobs and other. * for serial job (with probability SerialProb) the number of nodes is 1 @@ -1177,7 +1232,7 @@ for (int i=moveto ; i<BUCKETS+moveto ; i++) { idx = (i-1)%BUCKETS; /* i-1 since array indices are 0..47 and not 1..48 */ weights[j][idx] = - gamcdf(i+0.5, anum[j], bnum[j]) - gamcdf(i-0.5, anum[j],bnum[j]); + gamcdf(((double)i)+0.5, anum[j], bnum[j]) - gamcdf(((double)i)-0.5, anum[j],bnum[j]); mean[j] += weights[j][idx]; } mean[j] /= BUCKETS; @@ -1276,19 +1331,13 @@ gl.setUserID( super.get_id() ); // set the owner ID gl.setNumPE(numProc); // set the requested num of proc - // printing to inform user - if (gridletID_ == 1 || gridletID_ % INTERVAL == 0) - { - System.out.println(super.get_name() + ": Submitting Gridlets to " + - resName_ + " ..."); - } - // check the submit time if (submitTime < 0) { submitTime = 0; } gridletID_++; // increment the counter + lastSubmissionTime_ = submitTime; // submit a gridlet to resource super.send(super.output, submitTime, GridSimTags.GRIDLET_SUBMIT, @@ -1372,6 +1421,22 @@ return (beta * x * y); } +// /* +// * betarndLess1 returns a value of a random variable of beta(alpha,beta) +// * distribution where both alpha and beta are smaller than 1 (and larger +// * than 0) +// */ +// private double betarndLess1(double alpha, double beta) { +// double x, y, u1, u2; +// do { +// u1 = random_.nextDouble(); +// u2 = random_.nextDouble(); +// x = Math.pow(u1, 1 / alpha); +// y = Math.pow(u2, 1 / beta); +// } while (x + y > 1); +// return (x / (x + y)); +// } + /* * betarndLess1 returns a value of a random variable of beta(alpha,beta) * distribution where both alpha and beta are smaller than 1 (and larger @@ -1382,8 +1447,8 @@ do { u1 = random_.nextDouble(); u2 = random_.nextDouble(); - x = Math.pow(u1, 1 / alpha); - y = Math.pow(u2, 1 / beta); + x = Math.pow(u1, 1D / alpha); + y = Math.pow(u2, 1D / beta); } while (x + y > 1); return (x / (x + y)); } Modified: branches/gridsim4.0-branch3/source/gridsim/turbo/MPAvailabilityProfile.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/turbo/MPAvailabilityProfile.java 2008-05-11 00:55:20 UTC (rev 173) +++ branches/gridsim4.0-branch3/source/gridsim/turbo/MPAvailabilityProfile.java 2008-05-19 04:23:04 UTC (rev 174) @@ -65,7 +65,7 @@ * @return a collection with the partitions in this * profile. */ - protected Collection<QueuePartition> getPartitions() { + public Collection<QueuePartition> getPartitions() { //TODO: To find a better way to do it... return queues_.values(); } @@ -1058,7 +1058,7 @@ * smaller, or whose time is equals to <tt>time</tt>; <tt>null</tt> if * not found. */ - protected MPProfileEntry getPrecedingEntry(double time) { + public MPProfileEntry getPrecedingEntry(double time) { Iterator<MPProfileEntry> it = super.iterator(); MPProfileEntry preceding = null; Added: branches/gridsim4.0-branch3/source/gridsim/turbo/WorkloadInterface.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/turbo/WorkloadInterface.java (rev 0) +++ branches/gridsim4.0-branch3/source/gridsim/turbo/WorkloadInterface.java 2008-05-19 04:23:04 UTC (rev 174) @@ -0,0 +1,63 @@ +/* + * Title: GridSim Toolkit + * Description: GridSim (Grid Simulation) Toolkit for Modeling and Simulation + * of Parallel and Distributed Systems such as Clusters and Grids + * Licence: GPL - http://www.gnu.org/copyleft/gpl.html + */ + +package gridsim.turbo; + +import eduni.simjava.Sim_event; +import gridsim.Gridlet; + +/** + * The main purpose of this interface is to give the user flexibility in creating + * entities that generate gridlets according to a trace file or a workload model. + * + * In other words, this interface defines methods that allow the user + * to change the behaviour of the entity when a new job is generated, or + * when jobs are returned by the resource providers. + * + * @author Marcos Dias de Assuncao + * + * @since GridSim Turbo Alpha 0.1 + * @invariant $none + */ +public interface WorkloadInterface { + + /** + * This method is called by a workload generator or model when once + * information for a gridlet is read from a log file or created by the model. + * @param gridletId the id assigned to the gridlet + * @param submitTime the time the gridlet should be submitted + * @param runTime the runtime estimate for the gridlet + * @param numProc the number of processors required by the gridlet + */ + void onGridletCreation(int gridletId, long submitTime, + int runTime, int numProc); + + /** + * This method is invoked when a Gridlet is returned by the resource + * back to a workload model or trace reader. + * @param grl the gridlet returned by the resource + */ + void onGridletReceipt(Gridlet grl); + + /** + * This method is invoked by the workload reader/model upon the scheduling + * of the last gridlet created. This is useful in case the user wants to + * schedule an event to cancel the simulation at the submission of the last + * job to avoid the cool down phase of the simulation. + * @param lastSubmissionTime the time when the last gridlet + * submission took place + */ + void finishGridletSubmission(double lastSubmissionTime); + + /** + * Invoked by the workload implementation when an event could not + * be handled. + * @param ev the event to be handled. + */ + void processOtherEvent(Sim_event ev); +} + Deleted: branches/gridsim4.0-branch3/source/gridsim/util/Workload.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/util/Workload.java 2008-05-11 00:55:20 UTC (rev 173) +++ branches/gridsim4.0-branch3/source/gridsim/util/Workload.java 2008-05-19 04:23:04 UTC (rev 174) @@ -1,939 +0,0 @@ -/* - * Title: GridSim Toolkit - * Description: GridSim (Grid Simulation) Toolkit for Modeling and Simulation - * of Parallel and Distributed Systems such as Clusters and Grids - * Licence: GPL - http://www.gnu.org/copyleft/gpl.html - * - */ - -package gridsim.util; - -import eduni.simjava.*; -import gridsim.*; -import gridsim.net.*; - -// below packages are needed to read a file -import java.util.*; -import java.util.zip.*; -import java.io.*; - -/** - * The main purpose of this class is to create a realistic simulation - * environment where your jobs or Gridlets are competing with others. - * In other words, the grid resource might not be available at certain times. - * In addition, the arrival time of jobs are also captured in the trace file. - * <p> - * This class is responsible for reading resource traces from a file and - * sends Gridlets to only <tt>one</tt> destinated resource. <br> - * <b>NOTE:</b> - * <ul> - * <li> This class can only take <tt>one</tt> trace file of the following - * format: <i>ASCII text, zip, gz.</i> - * <li> This class can be classified as <b>one grid user entity</b>. - * Hence, you need to incorporate this entity into <tt>numUser</tt> - * during {@link gridsim.GridSim#init(int, Calendar, boolean)} - * <li> If you need to use multiple trace files to submit Gridlets to - * same or different resources, then you need to create multiple - * instances of this class <tt>each with a unique entity name</tt>. - * <li> If size of the trace file is huge or contains lots of traces - * please increase the JVM heap size accordingly by using - * <tt>java -Xmx</tt> option when running the simulation. - * <li> If you are running an experiment using the network extension, - * i.e. the gridsim.net package, then you need to use - * {@link #Workload(String, double, double, int, String, String, int)} - * instead. - * <li> The default job file size for sending to and receiving from - * a resource is {@link gridsim.net.Link#DEFAULT_MTU}. - * However, you can specify - * the file size by using {@link #setGridletFileSize(int)}. - * <li> A job run time is only for 1 PE <tt>not</tt> the total number of - * allocated PEs. - * Therefore, a Gridlet length is also calculated for 1 PE.<br> - * For example, job #1 in the trace has a run time of 100 seconds - * for 2 processors. This means each processor runs - * job #1 for 100 seconds, if the processors have the same - * specification. - * </ul> - * <p> - * By default, this class follows the standard workload format as specified - * in <a href="http://www.cs.huji.ac.il/labs/parallel/workload/"> - * http://www.cs.huji.ac.il/labs/parallel/workload/</a> <br> - * However, you can use other format by calling the below methods before - * running the simulation: - * <ul> - * <li> {@link #setComment(String)} - * <li> {@link #setField(int, int, int, int, int)} - * </ul> - * - * @see gridsim.GridSim#init(int, Calendar, boolean) - * @author Anthony Sulistio - * @since GridSim Toolkit 3.1 - * @invariant $none - */ -public class Workload extends GridSim -{ - protected String fileName_; // file name - protected String resName_; // resource name - protected int resID_; // resource ID - protected int rating_; // a PE rating - protected int gridletID_; // gridletID - protected int size_; // job size for sending it through a network - protected ArrayList list_; // a list for getting all the Gridlets - - // constant - private int JOB_NUM; // job number - private int SUBMIT_TIME; // submit time of a Gridlet - private int RUN_TIME; // running time of a Gridlet - private int NUM_PROC; // number of processors needed for a Gridlet - private int REQ_NUM_PROC; // required number of processors - private int REQ_RUN_TIME; // required running time - private int MAX_FIELD; // max number of field in the trace file - private String COMMENT; // a string that denotes the start of a comment - private final int IRRELEVANT = -1; // irrelevant number - private String[] fieldArray_; // a temp array storing all the fields - - /** - * Create a new Workload object <b>without</b> using the network extension. - * This means this entity directly sends Gridlets to a destination resource - * without going through a wired network. <br> - * <tt>NOTE:</tt> - * You can not use this constructor in an experiment that uses a wired - * network topology. - * - * @param name this entity name - * @param fileName the workload trace filename in one of the following - * format: <i>ASCII text, zip, gz.</i> - * @param resourceName the resource name - * @param rating the resource's PE rating - * @throws Exception This happens when creating this entity before - * initialising GridSim package or this entity name is - * <tt>null</tt> or empty - * @throws ParameterException This happens for the following conditions: - * <ul> - * <li>the entity name is null or empty - * <li>the workload trace file name is null or empty - * <li>the resource entity name is null or empty - * <li>the resource PE rating <= 0 - * </ul> - * @pre name != null - * @pre fileName != null - * @pre resourceName != null - * @pre rating > 0 - * @post $none - */ - public Workload(String name, String fileName, String resourceName, - int rating) throws ParameterException, Exception - { - super(name, GridSimTags.DEFAULT_BAUD_RATE); - - // check the input parameters first - String msg = name + "(): Error - "; - if (fileName == null || fileName.length() == 0) { - throw new ParameterException(msg + "invalid trace file name."); - } - else if (resourceName == null || resourceName.length() == 0) { - throw new ParameterException(msg + "invalid resource name."); - } - else if (rating <= 0) { - throw new ParameterException(msg+"resource PE rating must be > 0."); - } - - System.out.println(name + ": Creating a workload object ..."); - init(fileName, resourceName, rating); - } - - /** - * Create a new Workload object <b>with</b> the network extension. - * This means this entity directly sends Gridlets to a destination resource - * through a link. The link is automatically created by this constructor. - * - * @param name this entity name - * @param baudRate baud rate of this link (bits/s) - * @param propDelay Propagation delay of the Link in milliseconds - * @param MTU Maximum Transmission Unit of the Link in bytes. - * Packets which are larger than the MTU should be split - * up into MTU size units. - * For example, a 1024 byte packet trying to cross a 576 - * byte MTU link should get split into 2 packets of 576 - * bytes and 448 bytes. - * @param fileName the workload trace filename in one of the following - * format: <i>ASCII text, zip, gz.</i> - * @param resourceName the resource name - * @param rating the resource's PE rating - * @throws Exception This happens when creating this entity before - * initialising GridSim package or this entity name is - * <tt>null</tt> or empty - * @throws ParameterException This happens for the following conditions: - * <ul> - * <li>the entity name is null or empty - * <li> baudRate <= 0 - * <li> propDelay <= 0 - * <li> MTU <= 0 - * <li>the workload trace file name is null or empty - * <li>the resource entity name is null or empty - * <li>the resource PE rating <= 0 - * </ul> - * @pre name != null - * @pre baudRate > 0 - * @pre propDelay > 0 - * @pre MTU > 0 - * @pre fileName != null - * @pre resourceName != null - * @pre rating > 0 - * @post $none - */ - public Workload(String name, double baudRate, double propDelay, int MTU, - String fileName, String resourceName, int rating) - throws ParameterException, Exception - { - super( name, new SimpleLink(name+"_link", baudRate, propDelay, MTU) ); - - // check the input parameters first - String msg = name + "(): Error - "; - if (fileName == null || fileName.length() == 0) { - throw new ParameterException(msg + "invalid trace file name."); - } - else if (resourceName == null || resourceName.length() == 0) { - throw new ParameterException(msg + "invalid resource name."); - } - else if (rating <= 0) { - throw new ParameterException(msg+"resource PE rating must be > 0."); - } - - System.out.println(name + ": Creating a workload object ..."); - init(fileName, resourceName, rating); - } - - /** - * Create a new Workload object <b>with</b> the network extension. - * This means this entity directly sends Gridlets to a destination resource - * through a link. The link is automatically created by this constructor. - * - * @param name this entity name - * @param link the link that will be used to connect this Workload - * to another entity or a Router. - * @param fileName the workload trace filename in one of the following - * format: <i>ASCII text, zip, gz.</i> - * @param resourceName the resource name - * @param rating the resource's PE rating - * @throws Exception This happens when creating this entity before - * initialising GridSim package or this entity name is - * <tt>null</tt> or empty - * @throws ParameterException This happens for the following conditions: - * <ul> - * <li>the entity name is null or empty - * <li>the link is empty - * <li>the workload trace file name is null or empty - * <li>the resource entity name is null or empty - * <li>the resource PE rating <= 0 - * </ul> - * @pre name != null - * @pre link != null - * @pre fileName != null - * @pre resourceName != null - * @pre rating > 0 - * @post $none - */ - public Workload(String name, Link link, String fileName, - String resourceName, int rating) - throws ParameterException, Exception - { - super(name, link); - - // check the input parameters first - String msg = name + "(): Error - "; - if (fileName == null || fileName.length() == 0) { - throw new ParameterException(msg + "invalid trace file name."); - } - else if (resourceName == null || resourceName.length() == 0) { - throw new ParameterException(msg + "invalid resource name."); - } - else if (rating <= 0) { - throw new ParameterException(msg+"resource PE rating must be > 0."); - } - - System.out.println(name + ": Creating a workload object ..."); - init(fileName, resourceName, rating); - } - - /** - * Initialises all the attributes - * @param fileName trace file name - * @param resourceName resource entity name - * @param rating resource PE rating - * @pre $none - * @post $none - */ - private void init(String fileName, String resourceName, int rating) - { - fileName_ = fileName; - resName_ = resourceName; - resID_ = GridSim.getEntityId(resName_); - rating_ = rating; - gridletID_ = 1; // starts at 1 to make it the same as in a trace file - list_ = null; - size_ = Link.DEFAULT_MTU; - - // if using Standard Workload Format -- don't forget to substract by 1 - // since an array starts at 0, but the field in a trace starts at 1 - JOB_NUM = 1 - 1; - SUBMIT_TIME = 2 - 1; - RUN_TIME = 4 - 1; - NUM_PROC = 5 - 1; - REQ_NUM_PROC = 8 - 1; - REQ_RUN_TIME = 9 - 1; - - COMMENT = ";"; // semicolon means the start of a comment - MAX_FIELD = 18; // standard workload format has 18 fields - fieldArray_ = null; - } - - /** - * Sets a Gridlet file size (in byte) for sending to/from a resource. - * @param size a Gridlet file size (in byte) - * @return <tt>true</tt> if it is successful, <tt>false</tt> otherwise - * @pre size > 0 - * @post $none - */ - public boolean setGridletFileSize(int size) - { - if (size < 0) { - return false; - } - - size_ = size; - return true; - } - - /** - * Identifies the start of a comment line. Hence, a line that starts - * with a given comment will be ignored. - * @param comment a character that denotes the start of a comment, - * e.g. ";" or "#" - * @return <tt>true</tt> if it is successful, <tt>false</tt> otherwise - * @pre comment != null - * @post $none - */ - public boolean setComment(String comment) - { - boolean success = false; - if (comment != null && comment.length() > 0) - { - COMMENT = comment; - success = true; - } - return success; - } - - /** - * Tells this class what to look in the trace file. - * This method should be called before the start of the simulation. - * <p> - * By default, this class follows the standard workload format as specified - * in <a href="http://www.cs.huji.ac.il/labs/parallel/workload/"> - * http://www.cs.huji.ac.il/labs/parallel/workload/</a> <br> - * However, you can use other format by calling this method. - * <p> - * The parameters must be a positive integer number starting from 1. - * A special case is where <tt>jobNum == -1</tt>, meaning the job or - * gridlet ID starts at 1. - * - * @param maxField max. number of field/column in one row - * @param jobNum field/column number for locating the job ID - * @param submitTime field/column number for locating the job submit time - * @param runTime field/column number for locating the job run time - * @param numProc field/column number for locating the number of PEs - * required to run a job - * @return <tt>true</tt> if successful, <tt>false</tt> otherwise - * @pre maxField > 0 - * @pre submitTime > 0 - * @pre runTime > 0 - * @pre numProc > 0 - * @post $none - */ - public boolean setField(int maxField, int jobNum, int submitTime, - int runTime, int numProc) - { - // need to substract by 1 since array starts at 0. Need to convert, - // position in a field into the index of the array - if (jobNum > 0) { - JOB_NUM = jobNum - 1; - } - else if (jobNum == 0) - { - System.out.println(super.get_name() + - ".setField(): Invalid job number field."); - return false; - } - else { - JOB_NUM = -1; - } - - // get the max. number of field - if (maxField > 0) { - MAX_FIELD = maxField; - } - else - { - System.out.println(super.get_name() + - ".setField(): Invalid max. number of field."); - return false; - } - - // get the submit time field - if (submitTime > 0) { - SUBMIT_TIME = submitTime - 1; - } - else - { - System.out.println(super.get_name() + - ".setField(): Invalid submit time field."); - return false; - } - - // get the run time field - if (runTime > 0) { - REQ_RUN_TIME = runTime - 1; - } - else - { - System.out.println(super.get_name() + - ".setField(): Invalid run time field."); - return false; - } - - // get the number of processors field - if (numProc > 0) { - REQ_NUM_PROC = numProc - 1; - } - else - { - System.out.println(super.get_name() + - ".setField(): Invalid number of processors field."); - return false; - } - - return true; - } - - /** - * Gets a list of completed Gridlets - * @return a list of Gridlets - * @pre $none - * @post $none - */ - public ArrayList getGridletList() { - return list_; - } - - /** - * Prints the Gridlet objects - * @param history <tt>true</tt> means printing each Gridlet's history, - * <tt>false</tt> otherwise - * @pre $none - * @post $none - */ - public void printGridletList(boolean history) - { - String name = super.get_name(); - int size = list_.size(); - Gridlet gridlet; - - String indent = " "; - System.out.println(); - System.out.println("========== OUTPUT for " + name + " =========="); - System.out.println("Gridlet_ID" + indent + "STATUS" + indent + - "Resource_ID" + indent + "Cost"); - - int i = 0; - for (i = 0; i < size; i++) - { - gridlet = (Gridlet) list_.get(i); - System.out.print(indent + gridlet.getGridletID() + indent - + indent); - - // get the status of a Gridlet - System.out.print( gridlet.getGridletStatusString() ); - System.out.println( indent + indent + gridlet.getResourceID() + - indent + indent + gridlet.getProcessingCost() ); - } - - System.out.println(); - if (history == true) - { - // a loop to print each Gridlet's history - System.out.println(); - for (i = 0; i < size; i++) - { - gridlet = (Gridlet) list_.get(i); - System.out.println( gridlet.getGridletHistory() ); - - System.out.print("Gridlet #" + gridlet.getGridletID() ); - System.out.println(", length = " + gridlet.getGridletLength() - + ", finished so far = " - + gridlet.getGridletFinishedSoFar() ); - System.out.println("========================================="); - System.out.println(); - } - } - } - - /** - * Reads from a given file when the simulation starts running. - * Then submits Gridlets to a resource and collects them before exiting. - * To collect the completed Gridlets, use {@link #getGridletList()} - * @pre $none - * @post $none - */ - public void body() - { - System.out.println(); - System.out.println(super.get_name() + ".body() :%%%% Start ..."); - - // create a temp array - fieldArray_ = new String[MAX_FIELD]; - - // get the resource id - if (resID_ < 0) - { - System.out.println(super.get_name() + - ".body(): Error - invalid resource name: " + resName_); - return; - } - - boolean success = false; - System.out.println(super.get_name() + ": Submitting Gridlets to " + - resName_ + " ..."); - - // read the gz file - if (fileName_.endsWith(".gz") == true) { - success = readGZIPFile(fileName_); - } - // read the zip file - else if (fileName_.endsWith(".zip") == true) { - success = readZipFile(fileName_); - } - // read from uncompressed file as well - else { - success = readFile(fileName_); - } - - // help the garbage collector - fieldArray_ = null; - - // if all the gridlets have been submitted - if (success == true) { - collectGridlet(); - } - else - { - System.out.println(super.get_name() + - ".body(): Error - unable to parse from a file."); - } - - // shut down all the entities, including GridStatistics entity since - // we used it to record certain events. - shutdownGridStatisticsEntity(); - shutdownUserEntity(); - terminateIOEntities(); - - System.out.println(super.get_name() + ".body() : %%%% Exit ..."); - } - - //////////////////////// PROTECTED METHODS /////////////////////// - - /** - * Collects Gridlets sent and stores them into a list. - * @pre $none - * @post $none - */ - protected void collectGridlet() - { - System.out.println(super.get_name() + ": Collecting Gridlets ..."); - list_ = new ArrayList(gridletID_ + 1); - - Object data = null; - Gridlet gl = null; - - int counter = 1; // starts at 1, since gridletID_ starts at 1 too - Sim_event ev = new Sim_event(); - while ( Sim_system.running() ) - { - super.sim_get_next(ev); // get the next available event - data = ev.get_data(); // get the event's data - - // handle ping request - if (ev.get_tag() == GridSimTags.INFOPKT_SUBMIT) - { - processPingRequest(ev); - continue; - } - - // get the Gridlet data - if (data != null && data instanceof Gridlet) - { - gl = (Gridlet) data; - list_.add(gl); - counter++; - } - - // if all the Gridlets have been collected - if (counter == gridletID_) { - break; - } - } - } - - /** - * Processes a ping request. - * @param ev a Sim_event object - * @pre ev != null - * @post $none - */ - protected void processPingRequest(Sim_event ev) - { - InfoPacket pkt = (InfoPacket) ev.get_data(); - pkt.setTag(GridSimTags.INFOPKT_RETURN); - pkt.setDestID( pkt.getSrcID() ); - - // sends back to the sender - super.send(super.output, GridSimTags.SCHEDULE_NOW, - GridSimTags.INFOPKT_RETURN, - new IO_data(pkt, pkt.getSize(), pkt.getSrcID()) ); - } - - //////////////////////// PRIVATE METHODS /////////////////////// - - /** - * Breaks a line of string into many fields. - * @param line a line of string - * @param lineNum a line number - * @pre line != null - * @pre lineNum > 0 - * @post $none - */ - private void parseValue(String line, int lineNum) - { - // skip a comment line - if (line.startsWith(COMMENT) == true) { - return; - } - - String[] sp = line.split("\\s+"); // split the fields based on a space - int i; // a counter - int len = 0; // length of a string - int index = 0; // the index of an array - - // check for each field in the array - for (i = 0; i < sp.length; i++) - { - len = sp[i].length(); // get the length of a string - - // if it is empty then ignore - if (len == 0) { - continue; - } - // if not, then put into the array - else - { - fieldArray_[index] = sp[i]; - index++; - } - } - - if (index == MAX_FIELD) { - extractField(fieldArray_, lineNum); - } - } - - /** - * Extracts relevant information from a given array - * @param array an array of String - * @param line a line number - * @pre array != null - * @pre line > 0 - */ - private void extractField(String[] array, int line) - { - try - { - Integer obj = null; - - // get the job number - int id = 0; - if (JOB_NUM == IRRELEVANT) { - id = gridletID_; - } - else { - obj = new Integer( array[JOB_NUM].trim() ); - id = obj.intValue(); - } - - // get the submit time - Long l = new Long( array[SUBMIT_TIME].trim() ); - long submitTime = l.intValue(); - - // get the run time - obj = new Integer( array[REQ_RUN_TIME].trim() ); - int runTime = obj.intValue(); - - // if the required run time field is ignored, then use - // the actual run time - if (runTime == IRRELEVANT) - { - obj = new Integer( array[RUN_TIME].trim() ); - runTime = obj.intValue(); - } - - // according to the SWF manual, runtime of 0 is possible due - // to rounding down. E.g. runtime is 0.4 seconds -> runtime = 0 - if (runTime == 0) { - runTime = 1; // change to 1 second - } - - // get the number of allocated processors - obj = new Integer( array[REQ_NUM_PROC].trim() ); - int numProc = obj.intValue(); - - // if the required num of allocated processors field is ignored - // or zero, then use the actual field - if (numProc == IRRELEVANT || numProc == 0) - { - obj = new Integer( array[NUM_PROC].trim() ); - numProc = obj.intValue(); - } - - // finally, check if the num of PEs required is valid or not - if (numProc <= 0) - { - System.out.println(super.get_name() + ": Warning - job #" - + id + " at line " + line + " requires " + numProc - + " CPU. Change to 1 CPU."); - numProc = 1; - } - - // submit a Gridlet - submitGridlet(id, submitTime, runTime, numProc); - } - catch (Exception e) - { - System.out.println(super.get_name() + - ": Exception in reading file at line #" + line); - e.printStackTrace(); - } - } - - /** - * Creates a Gridlet with the given information, then submit it to a - * resource - * @param id a Gridlet ID - * @param submitTime Gridlet's submit time - * @param runTime Gridlet's actual run time - * @param numProc number of processors - * @pre id >= 0 - * @pre submitTime >= 0 - * @pre runTime >= 0 - * @pre numProc > 0 - * @post $none - */ - protected void submitGridlet(int id, long submitTime, - int runTime, int numProc) - { - // create the gridlet - int len = runTime * rating_; // calculate a job length for each PE - Gridlet gl = new Gridlet(id, len, size_, size_, GridSim.isTraceEnabled()); - gl.setUserID( super.get_id() ); // set the owner ID - gl.setNumPE(numProc); // set the requested num of proc - - // check the submit time - if (submitTime < 0) { - submitTime = 0; - ... [truncated message content] |
From: <mar...@us...> - 2008-06-13 00:55:13
|
Revision: 183 http://gridsim.svn.sourceforge.net/gridsim/?rev=183&view=rev Author: marcos_dias Date: 2008-06-12 17:55:20 -0700 (Thu, 12 Jun 2008) Log Message: ----------- This update contains a few changes in the workload model, which allows one to extend the model in an easier way. It also provides the capability to query for particular free time slots from providers. Modified Paths: -------------- branches/gridsim4.0-branch3/examples/examples/workload/parallel/LublinWorkloadExample01.java branches/gridsim4.0-branch3/source/gridsim/turbo/AvailabilityInfo.java branches/gridsim4.0-branch3/source/gridsim/turbo/Lublin99Workload.java branches/gridsim4.0-branch3/source/gridsim/turbo/SSGridlet.java branches/gridsim4.0-branch3/source/gridsim/turbo/WorkloadInterface.java Modified: branches/gridsim4.0-branch3/examples/examples/workload/parallel/LublinWorkloadExample01.java =================================================================== --- branches/gridsim4.0-branch3/examples/examples/workload/parallel/LublinWorkloadExample01.java 2008-05-30 16:57:03 UTC (rev 182) +++ branches/gridsim4.0-branch3/examples/examples/workload/parallel/LublinWorkloadExample01.java 2008-06-13 00:55:20 UTC (rev 183) @@ -69,6 +69,7 @@ int rating = 377; // rating of each PE in MIPS int totalPE = 9; // total number of PEs for each Machine int totalMachine = 128; // total number of Machines + int i = 0; String[] resArray = new String[totalResource]; @@ -93,11 +94,19 @@ // uHi is going to contain log2 of the maximum number of PEs that a // parallel job can require double uHi = Math.log(totalPE * totalMachine) / Math.log(2d); - double uMed = uHi-2.5; - + + /* Here we modify the number of nodes required by parallel jobs + * as an example */ + double uMed = uHi-3.5; workload.setParallelJobProbabilities(Lublin99Workload.INTERACTIVE_JOBS, workload.getParallelJobULow(Lublin99Workload.INTERACTIVE_JOBS), uMed, uHi, workload.getParallelJobUProb(Lublin99Workload.INTERACTIVE_JOBS)); + + /* Here we modify the inter-arrival time for jobs as an example */ +// workload.setInterArrivalTimeParameters(Lublin99Workload.INTERACTIVE_JOBS, +// Lublin99Workload.AARR, 0.55D, +// Lublin99Workload.ANUM, Lublin99Workload.BNUM, +// Lublin99Workload.ARAR); // sets the workload to create 1000 jobs workload.setNumJobs(1000); Modified: branches/gridsim4.0-branch3/source/gridsim/turbo/AvailabilityInfo.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/turbo/AvailabilityInfo.java 2008-05-30 16:57:03 UTC (rev 182) +++ branches/gridsim4.0-branch3/source/gridsim/turbo/AvailabilityInfo.java 2008-06-13 00:55:20 UTC (rev 183) @@ -391,10 +391,15 @@ * they are not the scheduling options for jobs. * @param startTime the start time of the period. * @param finishTime the finish time of the period. + * @param duration the minimum duration of the free time slots. Free time slots + * whose time frame is smaller than <tt>duration</tt> will be ignored. + * @param numPEs the minimum number of PEs of the free time slots. Free time slots + * whose number of PEs is smaller than <tt>numPEs</tt> will be ignored. * @return a linked list with the time slots contained in this availability * information object within a specified period of time. */ - public LinkedList<TimeSlot> getSchedulingOptions(double startTime, double finishTime) { + public LinkedList<TimeSlot> getSchedulingOptions(double startTime, + double finishTime, int duration, int numPEs) { LinkedList<TimeSlot> slots = new LinkedList<TimeSlot>(); // start time cannot be smaller than the start time of the info obj @@ -431,13 +436,17 @@ double endTime = entry.getTime(); boolean different = !intersect.equals(slotRanges); if(j < (size-1) && different) { - TimeSlot slot = new TimeSlot(slotStart, endTime, slotRanges); - slots.add(slot); + if((endTime - slotStart) >= duration && slotRanges.getNumPE() >= numPEs) { + TimeSlot slot = new TimeSlot(slotStart, endTime, slotRanges); + slots.add(slot); + } slotRanges = intersect; } else if (j == (size-1)) { - TimeSlot slot = new TimeSlot(slotStart, finishTime, slotRanges); - slots.add(slot); + if((endTime - slotStart) >= duration && slotRanges.getNumPE() >= numPEs) { + TimeSlot slot = new TimeSlot(slotStart, finishTime, slotRanges); + slots.add(slot); + } continue; } Modified: branches/gridsim4.0-branch3/source/gridsim/turbo/Lublin99Workload.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/turbo/Lublin99Workload.java 2008-05-30 16:57:03 UTC (rev 182) +++ branches/gridsim4.0-branch3/source/gridsim/turbo/Lublin99Workload.java 2008-06-13 00:55:20 UTC (rev 183) @@ -47,6 +47,168 @@ * specification. * </ul> * <p> + * Details on how the distributions have been implemented and how their + * parameters can be configured are described below. Please note that this text + * was extracted from the C implementation of the model performed by Uri Lublin + * and Dror Feitelson: + * + * <p> + * The load generated can be changed by changing the values of the model parameters. + * Remember to set the number-of-nodes' parameters to fit your system. + * I distinguish between the two different types (batch or interactive) if the + * useJobType in the constructors is set to <tt>true</tt>. The program starts + * by initialising the model's parameters (according to the following constants + * definitions -- parameters values). Notice that if job type is set to + * <tt>true</tt>, there are different values to batch-parameters and + * interactive-parameters, and if this flag is <tt>false</tt> then they both get + * the same value (and the arbitrary type interactive). The workload calculates + * for each job its arrival arrival time (using 2 gamma distributions), + * number of nodes (using a two-stage-uniform distribution), runtime + * (using the number of nodes and hyper-gamma distribution) and type. + * + * <p> + * Some definitions: + * <ul> + * <li> 'l' - the mean load of the system + * <li> 'r' - the mean runtime of a job + * <li> 'ri' - the runtime of job 'i' + * <li> 'n' - the mean number of nodes of a job + * <li> 'ni' - the number of nodes of job 'i' + * <li> 'a' - the mean inter-arrival time of a job + * <li> 'ai' - the arrival time (from the beginning of the simulation) of job 'i' + * <li> 'P' - the number of nodes in the system (the system's size). + * </ul> + * + * Given ri,ni,ai,N or r,n,a,N we can calculate the expected load on the system + * + * <p> + * <tt> + * sum(ri * ni) + * load = --------------- + * P * max(ai) + * </tt> + * + * <p> + * We can calculate an approximation (exact if 'ri' and 'ni' are independent) + * + *<p> + *<tt> + * r * n + * approximate-load = ------- + * P * a + *</tt> + * + * <p> + * The model controls the r,m,a. + * One can change them by changing the values of the model's parameters. + * + * <p> + * ---------------------- <br> + * Changing the runtime: <br> + * ---------------------- <br> + * Let g ~ gamma(alpha,beta) then the expectation and variation of g are:<br> + * E(g) = alpha*beta ; Var(g) = alpha*(beta^2)<br> + * so the coefficient of variation is CV = sqrt(Var(g))/E(g) = 1/sqrt(alpha). + * One who wishes to enlarge the gamma random value without changing the CV + * can set a larger value to the parameter beta . If one wishes that the CV will + * change he may set a larger value to alpha parameter. + * Let hg ~ hyper-gamma(a1,b1,a2,b2,p) then the expectation and variation are: <br> + * E(hg) = p*a1*b1 + (1-p)*a2*b2<br> + * Var(hg) = p^2*a1*b1^2 + (1-p)^2*a2*b2^2<br> + * One who wishes to enlarge the hyper-gamma (or the runtime) random value may + * do that using one (or more) of the three following ways:<br> + * 1. enlarge the first gamma.<br> + * 2. and/or enlarge the second gamma.<br> + * 3. and/or set a smaller value to the 'p' parameter.(parameter p of hyper-gamma + * is the proportion of the first gamma). + * since in my model 'p' is dependent on the number of nodes (p=pa*nodes+pb) + * this is done by diminishing 'pa' and/or diminishing 'pb' such that 'p' + * will be smaller. Note that changing 'pa' affects the correlation + * between the number of nodes a job needs and its runtime. <br> + * <br> + * Use {@link #setRunTimeParameters(int, double, double, double, double, double, double)} + * in order to change the runtime parameters of jobs. + * + * <p> + * ------------------------ <br> + * Changing the correlation between the number of nodes a job needs and its runtime: <br> + * ------------------------ <br> + * The parameter 'pa' is responsible for that correlation. Since its negative + * as the number of nodes get larger so is the runtime. + * One who wishes no correlation between the nodes-number and the runtime should + * set 'pa' to be 0 or a small negative number close to 0. + * One who wishes to have strong such a correlation should set 'pa' to be not so + * close to 0 , for example -0.05 or -0.1 . Note that this affect the runtime + * which will be larger. One can take care of that by changing the other runtime + * parameters (a1,b1,a2,b2,pb). <br> + * + * <p> + * ----------------------------- <br> + * Changing the number of nodes: <br> + * ----------------------------- <br> + * Let u ~ uniform(a,b) then the expectation of u is E(u) = (a+b)/2. <br> + * Let tsu ~ two-stage-uniform(Ulow,Umed,Uhi,Uprob) then the expectation of tsu + * is E(tsu) = Uprob*(Ulow+Umed)/2 + (1-Uprob)*(Umed+Uhi)/2 = + * = (Uprob*Ulow + Umed + (1-Uprob)*Uhi)/2. <br> + * 'Ulow' is the log2 of the minimal number of nodes a job may run on. <br> + * 'Uhi' is the log2 of the system size. <br> + * 'Umed' is the changing point of the cdf function and should be set to <br> + * 'Umed' = 'Uhi' - 2.5. ('2.5' could be change between 1.5 to 3.5). <br> + * For example if the system size is 8 (Uhi = log2(8) = 3) its make no sense to + * set Umed to be 0 or 0.5 . In this case I would set Umed to be 1.5 , and maybe + * set Ulow to be 0.8 , so the probability of 2 would not be too small. + * 'Uprob' is the proportion of the first uniform (Ulow,Umed) and should be set + * to a value between 0.7 to 0.95. + *<br> + * One who wishes to enlarge the mean number of nodes may do that using one of + * the two following ways:<br> + * 1. set a smaller value to 'prob'<br> + * 2. and/or enlarge 'med'<br> + * Remember that changing the mean number of nodes will affect on the runtime + * too. <br> + * Use {@link #setParallelJobProbabilities(int, double, double, double, double)} + * to change the number of nodes and probability of parallel jobs. <br> + * Use {@link #setPower2Probability(int, double)} to change the probability of + * power of two jobs. <br> + * Use {@link #setSerialProbability(int, double)} to change the probability for + * serial or sequential jobs. <br> + * + * <p> + * -------------------------- <br> + * Changing the arrival time: <br> + * -------------------------- <br> + * The arrival time is calculated in two stages: <br> + * First stage : calculate the proportion of number of jobs arrived at every + * time interval (bucket). this is done using the gamma(anum,bnum) + * cdf and the CYCLIC_DAY_START. The weights array holds the points + * of all the buckets. <br> + * Second stage: foreach job calculate its inter-arrival time: <br> + * Generate a random value from the gamma(aarr,barr). + * The exponential of the random value is the + * points we have. While we have less points than the current + * bucket , "pay" the appropriate number of points and move to the + * next bucket (updating the next-arrival-time). + * <br> + * The parameters 'aarr' and 'barr' represent the inter-arrival-time in the + * rush hours. The parameters 'anum' and 'bnum' represent the number of jobs + * arrived (for every bucket). The proportion of bucket 'i' is: + * cdf (i+0.5 , anum , bnum) - cdf(i-0.5 , anum , bnum). + * We calculate this proportion foreach i from BUCKETS to (24+BUCKETS) , + * and the buckets (their indices) that are larger than or equal to 24 are move + * cyclically to the right place: + * (24 --> 0 , 25 --> 1 , ... , (24+BUCKETS) --> BUCKETS ) + * <br> + * One who wishes to change the mean inter-arrival time may do that in the + * following way: <br> + * - enlarge the rush-hours-inter-arrival time. + * This is done by enlarging the value of aarr or barr according to the wanted + * change of the CV. <br> + * One who wishes to change the daily cycle may change the values of 'anum' + * and/or 'bnum'<br> + * Use {@link #setInterArrivalTimeParameters(int, double, double, double, double, double)} + * to change the inter-arrival parameters. + * + * <p> * For more information on the workload model implemented here, please read * the following paper: <br> * Uri Lublin and Dror G. Feitelson, The Workload on Parallel Supercomputers: @@ -111,32 +273,40 @@ // ------------------- MODEL DEFAULT PARAMETERS ----------------------- - /* The parameters for number of nodes: - * serial_prob is the proportion of the serial jobs - * pow2_prob is the proportion of the jobs with power 2 number of nodes - * ULow , UMed , UHi and Uprob are the parameters for the two-stage-uniform - * which is used to calculate the number of nodes for parallel jobs. - * ULow is the log2 of the minimal size of job in the system (you can add or - * subtract 0.2 to give less/more probability to the minimal size) . - * UHi is the log2 of the maximal size of a job in the system (system's size) - * UMed should be in [UHi-1.5 , UHi-3.5] - * Uprob should be in [0.7 - 0.95] - */ - private static final double SERIAL_PROB_BATCH = 0.2927; - private static final double POW2_PROB_BATCH = 0.6686; - private static final double ULOW_BATCH = 1.2f; // smallest parallel batch job has 2 nodes - private static final double UMED_BATCH = 5; - private static final double UHI_BATCH = 7; // biggest batch job has 128 nodes - private static final double UPROB_BATCH = 0.875; + /** The default proportion of batch serial jobs */ + public static final double SERIAL_PROB_BATCH = 0.2927; + /** The default proportion of batch jobs with power 2 number of nodes */ + public static final double POW2_PROB_BATCH = 0.6686; + + /** ULow, UMed, UHi and Uprob are the parameters for the two-stage-uniform + * which is used to calculate the number of nodes for parallel jobs. + * ULow is the default log2 of the minimal size of job in the system for batch jobs. */ + public static final double ULOW_BATCH = 1.2f; // smallest parallel batch job has 2 nodes + /** UHi is the default log2 of the maximal size of a batch job in the system (system's size) */ + public static final double UHI_BATCH = 7; // biggest batch job has 128 nodes + /** Default UMed for batch jobs. Note that UMed should be in [UHi-1.5 , UHi-3.5] */ + public static final double UMED_BATCH = 5; + /** Default UProb for batch jobs. Note that Uprob should be in [0.7 - 0.95] */ + public static final double UPROB_BATCH = 0.875; - private static final double SERIAL_PROB_ACTIVE = 0.1541; - private static final double POW2_PROB_ACTIVE = 0.625; - private static final double ULOW_ACTIVE = 1; // smallest interactive parallel job has 2 nodes - private static final double UMED_ACTIVE = 3; - private static final double UHI_ACTIVE = 5.5f; // biggest interactive job has 45 nodes - private static final double UPROB_ACTIVE = 0.705; + /** The default proportion of interactive serial jobs */ + public static final double SERIAL_PROB_ACTIVE = 0.1541; + /** The default proportion of interactive jobs with power 2 number of nodes */ + public static final double POW2_PROB_ACTIVE = 0.625; - /* The parameters for the running time + /** ULow, UMed, UHi and Uprob are the parameters for the two-stage-uniform + * which is used to calculate the number of nodes for parallel jobs. + * ULow is the default log2 of the minimal size of job in the system for interactive jobs. */ + public static final double ULOW_ACTIVE = 1; // smallest interactive parallel job has 2 nodes + /** UHi is the default log2 of the maximal size of an interactive job in the system (system's size) */ + public static final double UHI_ACTIVE = 5.5f; // biggest interactive job has 45 nodes + /** Default UMed for interactive jobs. Note that UMed should be in [UHi-1.5 , UHi-3.5] */ + public static final double UMED_ACTIVE = 3; + /** Default UProb for interactive jobs. Note that Uprob should be in [0.7 - 0.95] */ + public static final double UPROB_ACTIVE = 0.705; + + /** + * The parameters for the running time * The running time is computed using hyper-gamma distribution. * The parameters a1,b1,a2,b2 are the parameters of the two gamma distributions * The p parameter of the hyper-gamma distribution is calculated as a straight @@ -144,19 +314,19 @@ * 'nodes' will be calculated in the program, here we defined the 'pa','pb' * parameters. */ - private static final double A1_BATCH = 6.57; - private static final double B1_BATCH = 0.823; - private static final double A2_BATCH = 639.1; - private static final double B2_BATCH = 0.0156; - private static final double PA_BATCH = -0.003; - private static final double PB_BATCH = 0.6986; + public static final double A1_BATCH = 6.57; + public static final double B1_BATCH = 0.823; + public static final double A2_BATCH = 639.1; + public static final double B2_BATCH = 0.0156; + public static final double PA_BATCH = -0.003; + public static final double PB_BATCH = 0.6986; - private static final double A1_ACTIVE = 3.8351; - private static final double B1_ACTIVE = 0.6605; - private static final double A2_ACTIVE = 7.073; - private static final double B2_ACTIVE = 0.6856; - private static final double PA_ACTIVE = -0.0118; - private static final double PB_ACTIVE = 0.9156; + public static final double A1_ACTIVE = 3.8351; + public static final double B1_ACTIVE = 0.6605; + public static final double A2_ACTIVE = 7.073; + public static final double B2_ACTIVE = 0.6856; + public static final double PA_ACTIVE = -0.0118; + public static final double PB_ACTIVE = 0.9156; /* The parameters for the inter-arrival time @@ -170,41 +340,41 @@ * a constant ,ARAR (Arrive-Rush-All-Ratio), to set the alpha parameter (the new * aarr) so it will represent the arrive-time at all hours of the day. */ - private static final double AARR_BATCH = 6.0415; - private static final double BARR_BATCH = 0.8531; - private static final double ANUM_BATCH = 6.1271; - private static final double BNUM_BATCH = 5.2740; - private static final double ARAR_BATCH = 1.0519; + public static final double AARR_BATCH = 6.0415; + public static final double BARR_BATCH = 0.8531; + public static final double ANUM_BATCH = 6.1271; + public static final double BNUM_BATCH = 5.2740; + public static final double ARAR_BATCH = 1.0519; - private static final double AARR_ACTIVE = 6.5510; - private static final double BARR_ACTIVE = 0.6621; - private static final double ANUM_ACTIVE = 8.9186; - private static final double BNUM_ACTIVE = 3.6680; - private static final double ARAR_ACTIVE = 0.9797; + public static final double AARR_ACTIVE = 6.5510; + public static final double BARR_ACTIVE = 0.6621; + public static final double ANUM_ACTIVE = 8.9186; + public static final double BNUM_ACTIVE = 3.6680; + public static final double ARAR_ACTIVE = 0.9797; /* * Here are the model's parameters for typeless data (no batch nor interactive) * We use those parameters when useJobType_ is false */ - private static final double SERIAL_PROB = 0.244; - private static final double POW2_PROB = 0.576; - private static final double ULOW = 0.8f; // The smallest parallel job is 2 nodes - private static final double UMED = 4.5f; - private static final double UHI = 7f; // SYSTEM SIZE is 2^UHI == 128 - private static final double UPROB = 0.86; + public static final double SERIAL_PROB = 0.244; + public static final double POW2_PROB = 0.576; + public static final double ULOW = 0.8f; // The smallest parallel job is 2 nodes + public static final double UMED = 4.5f; + public static final double UHI = 7f; // SYSTEM SIZE is 2^UHI == 128 + public static final double UPROB = 0.86; - private static final double A1 = 4.2; - private static final double B1 = 0.94; - private static final double A2 = 312; - private static final double B2 = 0.03; - private static final double PA = -0.0054; - private static final double PB = 0.78; + public static final double A1 = 4.2; + public static final double B1 = 0.94; + public static final double A2 = 312; + public static final double B2 = 0.03; + public static final double PA = -0.0054; + public static final double PB = 0.78; - private static final double AARR = 10.2303; - private static final double BARR = 0.4871; - private static final double ANUM = 8.1737; - private static final double BNUM = 3.9631; - private static final double ARAR = 1.0225; + public static final double AARR = 10.2303; + public static final double BARR = 0.4871; + public static final double ANUM = 8.1737; + public static final double BNUM = 3.9631; + public static final double ARAR = 1.0225; // start the simulation at midnight (hour 0) private static final int START = 0; @@ -515,13 +685,15 @@ barr[BATCH_JOBS] = barr[INTERACTIVE_JOBS] = BARR; anum[BATCH_JOBS] = anum[INTERACTIVE_JOBS] = ANUM; bnum[BATCH_JOBS] = bnum[INTERACTIVE_JOBS] = BNUM; + + timeFromBegin_[BATCH_JOBS] = Long.MAX_VALUE; } // if ( ! useJobType_ ) // make all jobs batch // timeFromBegin_[INTERACTIVE_JOBS] = Long.MAX_VALUE; - if ( ! useJobType_ ) // make all jobs interactive - timeFromBegin_[BATCH_JOBS] = Long.MAX_VALUE; +// if ( ! useJobType_ ) // make all jobs interactive +// timeFromBegin_[BATCH_JOBS] = Long.MAX_VALUE; } /** @@ -760,17 +932,25 @@ } /** - * Sets the parameters for the inter-arrival time - * The inter-arriving time is calculated using two gamma distributions. - * gamma(aarr,barr) represents the inter_arrival time for the rush hours. - * It is independent on the hour the job arrived at. - * The cdf of gamma(bnum,anum) represents the proportion of number of jobs - * which arrived at each time interval (bucket). - * The inter-arrival time is calculated using both gammas - * Since gamma(aarr,barr) represents the arrive-time at the rush time, - * we use a constant, ARAR (Arrive-Rush-All-Ratio), to set the alpha - * parameter (the new aarr) so it will represent the arrive-time at all - * hours of the day. + * Sets the parameters for the inter-arrival time. <br> + * The inter-arrival time is calculated using two gamma distributions. + * gamma(aarr,barr) represents the inter-arrival time for the rush hours. + * It is independent on the hour the job arrived at. The cdf of + * gamma(bnum,anum) represents the proportion of number of jobs which + * arrived at each time interval (bucket). The inter-arrival time is + * calculated using both gammas. Since gamma(aarr,barr) represents the + * arrival-time at the rush time, we use a constant, ARAR + * (Arrive-Rush-All-Ratio), to set the alpha parameter (the new aarr) + * so it will represent the arrive-time at all hours of the day. + * @param jobType the type of job for which the inter-arrival parameters + * will be modified. + * @param aarr the first parameter for gamma(aarr,barr) distribution + * @param barr the second parameter for gamma(aarr,barr) distribution + * @param anum the first parameter for gamma(bnum,anum) distribution + * @param bnum the second parameter for gamma(bnum,anum) distribution + * @param arar Arrive-Rush-All-Ratio + * @return <tt>true</tt> if the parameters have been set; + * <tt>false</tt> if they have not been set. */ public boolean setInterArrivalTimeParameters(int jobType, double aarr, double barr, double anum, double bnum, double arar) { @@ -842,7 +1022,7 @@ * The workload model will stop when it approaches workloadDuration. * @param workloadDuration the maximum duration of the workload. * @return <tt>true</tt> if the duration has been set; - * <tt>false</tt> othwerwise. + * <tt>false</tt> otherwise. */ public boolean setMaximumWorkloadDuration(double workloadDuration) { if(workloadDuration <= 0) @@ -1153,8 +1333,10 @@ par = twoStageUniform(uLow, uMed, uHi, uProb); if (u <= (serialProb + pow2Prob)) // power of 2 nodes parallel job par = (int)(par + 0.5); // par = round(par) - - return (int)(Math.pow(2, par) + 0.5); // return round(2^par) + + int numNodes = (int)(Math.pow(2, par) + 0.5); // round(2^par) + int maxNodes = (int)(Math.pow(2, uHi) + 0.5); + return numNodes <= maxNodes ? numNodes : maxNodes; } /* @@ -1345,9 +1527,9 @@ } - // --- Methods required by the distributions used by the workload model --- - // --- Most of these methods were ported from C to Java, but the logic --- - // --- remains the same as in Lublin's workload model in C --- + // --- Methods required by the distributions used by the workload model --- + // --- Most of these methods were ported from C to Java, but the logic --- + // --- remains the same as in Lublin's workload model in originally in C --- /* * hyperGamma returns a value of a random variable of mixture of two @@ -1421,22 +1603,6 @@ return (beta * x * y); } -// /* -// * betarndLess1 returns a value of a random variable of beta(alpha,beta) -// * distribution where both alpha and beta are smaller than 1 (and larger -// * than 0) -// */ -// private double betarndLess1(double alpha, double beta) { -// double x, y, u1, u2; -// do { -// u1 = random_.nextDouble(); -// u2 = random_.nextDouble(); -// x = Math.pow(u1, 1 / alpha); -// y = Math.pow(u2, 1 / beta); -// } while (x + y > 1); -// return (x / (x + y)); -// } - /* * betarndLess1 returns a value of a random variable of beta(alpha,beta) * distribution where both alpha and beta are smaller than 1 (and larger @@ -1543,38 +1709,51 @@ return tsu; } +// /* +// * Natural logarithm of gamma function +// */ +// static double logGamma(double x) { +// double tmp = (x - 0.5) * Math.log(x + 4.5) - (x + 4.5); +// double ser = 1.0 + 76.18009173 / (x + 0) - 86.50532033 / (x + 1) +// + 24.01409822 / (x + 2) - 1.231739516 / (x + 3) +// + 0.00120858003 / (x + 4) - 0.00000536382 / (x + 5); +// return tmp + Math.log(ser * Math.sqrt(2 * Math.PI)); +// } + + private double A[] = { + 8.11614167470508450300E-4, + -5.95061904284301438324E-4, + 7.93650340457716943945E-4, + -2.77777777730099687205E-3, + 8.33333333333331927722E-2 }; + + private double B[] = { + -1.37825152569120859100E3, + -3.88016315134637840924E4, + -3.31612992738871184744E5, + -1.16237097492762307383E6, + -1.72173700820839662146E6, + -8.53555664245765465627E5 }; + + private double C[] = { + // 1.00000000000000000000E0, + -3.51815701436523470549E2, + -1.70642106651881159223E4, + -2.20528590553854454839E5, + -1.13933444367982507207E6, + -2.53252307177582951285E6, + -2.01889141433532773231E6 }; + /* * Natural logarithm of gamma function * Cephes Math Library Release 2.2: July, 1992 * Copyright 1984, 1987, 1989, 1992 by Stephen L. Moshier * Direct inquiries to 30 Frost Street, Cambridge, MA 02140 */ - static private double logGamma(double x) + private double logGamma(double x) throws ArithmeticException { double p, q, w, z; - double A[] = { 8.11614167470508450300E-4, - -5.95061904284301438324E-4, - 7.93650340457716943945E-4, - -2.77777777730099687205E-3, - 8.33333333333331927722E-2 }; - - double B[] = { -1.37825152569120859100E3, - -3.88016315134637840924E4, - -3.31612992738871184744E5, - -1.16237097492762307383E6, - -1.72173700820839662146E6, - -8.53555664245765465627E5 }; - - double C[] = { - // 1.00000000000000000000E0, - -3.51815701436523470549E2, - -1.70642106651881159223E4, - -2.20528590553854454839E5, - -1.13933444367982507207E6, - -2.53252307177582951285E6, - -2.01889141433532773231E6 }; - if (x < -34.0) { q = -x; w = logGamma(q); @@ -1631,7 +1810,7 @@ return q; } - static private double polevl(double x, double coef[], int N) + private double polevl(double x, double coef[], int N) throws ArithmeticException { double ans; ans = coef[0]; @@ -1641,7 +1820,7 @@ return ans; } - static private double p1evl(double x, double coef[], int N) + private double p1evl(double x, double coef[], int N) throws ArithmeticException { double ans; ans = x + coef[0]; Modified: branches/gridsim4.0-branch3/source/gridsim/turbo/SSGridlet.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/turbo/SSGridlet.java 2008-05-30 16:57:03 UTC (rev 182) +++ branches/gridsim4.0-branch3/source/gridsim/turbo/SSGridlet.java 2008-06-13 00:55:20 UTC (rev 183) @@ -411,7 +411,7 @@ /** * Gets the submission or arrival time of this Gridlet from * the latest GridResource - * @return the submission time or <tt>0.0</tt> if nono + * @return the submission time or <tt>0.0</tt> if none */ public double getSubmissionTime() { return gridlet_.getSubmissionTime(); Modified: branches/gridsim4.0-branch3/source/gridsim/turbo/WorkloadInterface.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/turbo/WorkloadInterface.java 2008-05-30 16:57:03 UTC (rev 182) +++ branches/gridsim4.0-branch3/source/gridsim/turbo/WorkloadInterface.java 2008-06-13 00:55:20 UTC (rev 183) @@ -1,6 +1,6 @@ /* * Title: GridSim Toolkit - * Description: GridSim (Grid Simulation) Toolkit for Modeling and Simulation + * Description: GridSim (Grid Simulation) Toolkit for Modelling and Simulation * of Parallel and Distributed Systems such as Clusters and Grids * Licence: GPL - http://www.gnu.org/copyleft/gpl.html */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mar...@us...> - 2008-06-17 07:21:08
|
Revision: 184 http://gridsim.svn.sourceforge.net/gridsim/?rev=184&view=rev Author: marcos_dias Date: 2008-06-17 00:21:14 -0700 (Tue, 17 Jun 2008) Log Message: ----------- This update contains bug fixes on the advance reservation policies. The cancellation of a reservation was not performed properly. Also, the option to get the scheduling options for a job was returning a list with incorrect slots. Modified Paths: -------------- branches/gridsim4.0-branch3/examples/examples/ar/ARTest.java branches/gridsim4.0-branch3/source/gridsim/turbo/ARParallelSpaceShared.java branches/gridsim4.0-branch3/source/gridsim/turbo/AvailabilityInfo.java branches/gridsim4.0-branch3/source/gridsim/turbo/TimeSlot.java Modified: branches/gridsim4.0-branch3/examples/examples/ar/ARTest.java =================================================================== --- branches/gridsim4.0-branch3/examples/examples/ar/ARTest.java 2008-06-13 00:55:20 UTC (rev 183) +++ branches/gridsim4.0-branch3/examples/examples/ar/ARTest.java 2008-06-17 07:21:14 UTC (rev 184) @@ -186,7 +186,7 @@ System.out.println("Availability information returned by the " + "Grid resource # " + resID + " at time # " + GridSim.clock() + - " is as follows: \n " + availability); + " is as follows: \n " + availability); // try immediate reservation, where starting time is 0 meaning // use current time as the start time @@ -209,6 +209,22 @@ if(reservation != null && reservation.getStatus() != Reservation.STATUS_FAILED) { System.out.println(super.get_name() + ": reservation has been accepted by "+ resName + " at time = " + GridSim.clock()); + +// availability = +// super.queryFreeTime(GridSim.clock(), Integer.MAX_VALUE, resID); +// +// System.out.println("Free time slots:\n" + +// availability.getSchedulingOptions(20, 10000, 80, 1)); + +// super.cancelReservation(reservation.getID()); + +// // queries the availability of the Grid resource +// availability = super.queryFreeTime(GridSim.clock(), Integer.MAX_VALUE, resID); +// +// System.out.println("Availability information returned by the " + +// "Grid resource # " + resID + " at time # " + GridSim.clock() + +// " after cancellation is as follows: \n " + availability); + success = true; } else { Modified: branches/gridsim4.0-branch3/source/gridsim/turbo/ARParallelSpaceShared.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/turbo/ARParallelSpaceShared.java 2008-06-13 00:55:20 UTC (rev 183) +++ branches/gridsim4.0-branch3/source/gridsim/turbo/ARParallelSpaceShared.java 2008-06-17 07:21:14 UTC (rev 184) @@ -435,9 +435,6 @@ boolean inProgress = sRes.getStatus() == Reservation.STATUS_IN_PROGRESS; - // sets the status of the reservation to cancelled - sRes.setStatus(Reservation.STATUS_CANCELLED); - // remove the reservation from the reservation table // and put it into the expiry table reservTable_.remove(reservationId); @@ -445,6 +442,9 @@ // remove/update the entries of the profile removeReservation(sRes); + + // sets the status of the reservation to cancelled + sRes.setStatus(Reservation.STATUS_CANCELLED); //----------------- USED FOR DEBUGGING PURPOSES ONLY ------------------- Modified: branches/gridsim4.0-branch3/source/gridsim/turbo/AvailabilityInfo.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/turbo/AvailabilityInfo.java 2008-06-13 00:55:20 UTC (rev 183) +++ branches/gridsim4.0-branch3/source/gridsim/turbo/AvailabilityInfo.java 2008-06-17 07:21:14 UTC (rev 184) @@ -130,6 +130,122 @@ */ public double getPotentialStartTime(double readyTime, int duration, int reqPE) { + return getPotentialStartTime(readyTime, duration, reqPE, Double.MAX_VALUE); + } + +// /** +// * Scans the entries in the availability info object returns the start +// * time of the first time frame over which a request with the characteristics +// * provided can be scheduled. +// * @param readyTime the method will consider potential start times +// * further in time than the value given by <tt>readyTime</tt>. +// * @param duration the duration of the request +// * @param reqPE the number of PEs required +// * @return the start time or <tt>-1</tt> if not found. +// */ +// public double getPotentialStartTime(double readyTime, +// int duration, int reqPE) { +// +// if(readyTime < startTime_) +// readyTime = startTime_; +// +// if(readyTime > finishTime_) +// return UNKNOWN; +// +// // the anchor index, the entry in the profile where +// // the request would be placed OR the closest entry to the +// // point where the anchor of the request would be placed +// int anchorIndex = -1; +// +// // a pointer to the anchor entry (described above) +// AvailabilityInfoEntry anchorEntry = null; +// +// double potStartTime = -1; // keep the potential start time of the request +// double potFinishTime = -1; // store the gridlet's expected finish time +// int length = super.size(); +// +// anchorEntry = getPrecedingEntry(readyTime); +// int firstAnchorIndex = super.indexOf(anchorEntry); +// if(firstAnchorIndex == -1) +// firstAnchorIndex = 0; +// +// for(int j=firstAnchorIndex; j<length; j++) { +// AvailabilityInfoEntry entry = super.get(j); +// anchorIndex = super.indexOf(entry); +// +// // scan the profile until an entry with enough PEs is found +// if(entry.getNumPE() < reqPE) { +// continue; +// } +// else { +// +// // sets the start time as the time of the entry +// if(entry.getTime() < readyTime) +// potStartTime = readyTime; +// else +// potStartTime = entry.getTime(); +// +// // calculates when the finish time will be if +// // the gridlet is put at this position +// potFinishTime = potStartTime + duration; +// +// // if an entry with enough PEs is found, then scan the list +// // from that point onwards analysing the intersection of +// // the ranges available in the entries until the +// // request expected completion time +// PERangeList intersectList = entry.getAvailRanges().clone(); +// +// // Look for the intersection of available ranges from +// // the anchor until the end of the profile or until +// // the entries are further than the expected completion time +// for(int i=anchorIndex+1; i<length; i++){ +// AvailabilityInfoEntry nextEntry = super.get(i); +// if(nextEntry.getTime() > potFinishTime){ +// break; +// } +// else{ +// // if the finish time is equals to the entry time, so there +// // is no need to check the intersection +// if(nextEntry.getTime() < potFinishTime) { +// intersectList = PERangeList.intersection(intersectList, +// nextEntry.getAvailRanges()); +// +// if(intersectList == null || intersectList.getNumPE() < reqPE) { +// break; +// } +// } +// } +// } +// // If a time slot with enough PEs has been found, then stop the search +// if(intersectList != null && intersectList.getNumPE() >= reqPE) { +// break; +// } +// } +// } +// +// // if the potential finish time is larger than the end time of +// // this list, then the request cannot be scheduled +// if(potFinishTime > finishTime_) { +// potStartTime = UNKNOWN; +// } +// +// return potStartTime; +// } + + /** + * Scans the entries in the availability info object returns the start + * time of the first time frame over which a request with the characteristics + * provided can be scheduled. + * @param readyTime the method will consider potential start times + * further in time than the value given by <tt>readyTime</tt>. + * @param duration the duration of the request + * @param reqPE the number of PEs required + * @param deadline the deadline of the job, the user is not interested in + * the start time if the job cannot be completed by the deadline + * @return the start time or <tt>-1</tt> if not found. + */ + public double getPotentialStartTime(double readyTime, + int duration, int reqPE, double deadline) { if(readyTime < startTime_) readyTime = startTime_; @@ -174,6 +290,11 @@ // the gridlet is put at this position potFinishTime = potStartTime + duration; + // The job would not complete before the deadline, then just + // return the potential start time as unknown + if(potFinishTime > deadline) + return UNKNOWN; + // if an entry with enough PEs is found, then scan the list // from that point onwards analysing the intersection of // the ranges available in the entries until the @@ -210,7 +331,7 @@ // if the potential finish time is larger than the end time of // this list, then the request cannot be scheduled - if(potFinishTime > finishTime_) { + if(potFinishTime > finishTime_ || potFinishTime > deadline) { potStartTime = UNKNOWN; } @@ -222,77 +343,16 @@ * can be scheduled or not. The method verifies whether there are enough * processing elements at the start time to serve the request and * whether enough elements will be available over the request's duration. - * @param startTime the start time of the request. + * @param readyTime the start time of the request. This is the time before + * which, the request will not be ready for scheduling. The user is not + * interested in starting the job before this time. * @param duration the duration of the request. * @param reqPE the number of processing elements required. * @return <tt>true</tt> if the request can be scheduled, * or <tt>false</tt> otherwise. */ - public boolean canSchedule(double startTime, int duration, int reqPE) { - - // calculate the reservation's finish time - double finishTime = startTime + duration; - - // a pointer to the anchor entry (described above) - AvailabilityInfoEntry anchorEntry = null; - - // the list of selected ranges - PERangeList intersectList = null; - - intersectList = null; - int length = super.size(); - double entryTime; - - int anchorIndex = -1; - - Iterator<AvailabilityInfoEntry> it = super.iterator(); - while(it.hasNext()) { - AvailabilityInfoEntry entry = it.next(); - entryTime = entry.getTime(); - if(entryTime > startTime) { - break; - } - else { - anchorEntry = entry; - } - } - - intersectList = (anchorEntry != null ) ? - anchorEntry.getAvailRanges().clone() : null; - - if(intersectList == null || intersectList.getNumPE() < reqPE) { - // there are not enough PEs available to serve the - // advance reservation request, then returns null - return false; - } - - anchorIndex = super.indexOf(anchorEntry); - - // Look for the intersection of available ranges from - // the anchor until the end of the profile or until - // the entries are further than the expected completion time - for(int i=anchorIndex+1; i<length; i++) { - AvailabilityInfoEntry nextEntry = super.get(i); - if(nextEntry.getTime() > finishTime){ - break; - } - else { - // if the finish time is equals to the entry time, so there - // is no need to check the intersection - if(nextEntry.getTime() < finishTime) { - intersectList = PERangeList.intersection(intersectList, - nextEntry.getAvailRanges()); - } - } - - if(intersectList == null || intersectList.getNumPE() < reqPE) { - // there are not enough PEs available to serve the - // advance reservation request, then returns null - return false; - } - } - - return true; + public boolean canSchedule(double readyTime, int duration, int reqPE) { + return canSchedule(readyTime, Double.MAX_VALUE, duration, reqPE); } /** @@ -300,19 +360,21 @@ * can be scheduled or not. The method verifies whether there are enough * processing elements during ready time until the deadline for the * specified duration. - * @param readyTime the start time of the request. - * @param deadline the deadline of the request + * @param readyTime the start time of the request. This is the time before + * which, the request will not be ready for scheduling. The user is not + * interested in starting the job before this time. + * @param deadline the deadline of the request. * @param duration the duration of the request. * @param reqPE the number of processing elements required. * @return <tt>true</tt> if the request can be scheduled, * or <tt>false</tt> otherwise. */ public boolean canSchedule(double readyTime, double deadline, - int duration, int reqPE) { + int duration, int reqPE) { - if(duration < deadline - readyTime) { + if(duration > (deadline - readyTime)) { System.out.println("AvailabilityInfo.canSchedule(): Duration cannot " + - "be smaller than (deadline - readyTime)."); + "be larger than (deadline - readyTime)."); return false; } else if(deadline < readyTime) { @@ -321,67 +383,8 @@ return false; } - // the list of selected ranges - PERangeList intersectList = null; - int length = super.size(); - double entryTime; - - int anchorIndex = -1; - - Iterator<AvailabilityInfoEntry> it = super.iterator(); - while(it.hasNext()) { - AvailabilityInfoEntry entry = it.next(); - entryTime = entry.getTime(); - if(entryTime < readyTime) { - continue; - } - - // calculate the reservation's finish time - double finishTime = entryTime + duration; - if(finishTime > deadline) { - return false; - } - - if(entry.getNumPE() < reqPE) { - continue; - } - else { - anchorIndex = super.indexOf(entry); - intersectList = entry.getAvailRanges().clone(); - - // Look for the intersection of available ranges from - // the anchor until the end of the profile or until - // the entries are further than the expected completion time - for(int i=anchorIndex+1; i<length; i++) { - AvailabilityInfoEntry nextEntry = super.get(i); - if(nextEntry.getTime() > finishTime){ - break; - } - else { - // if the finish time is equals to the entry time, so there - // is no need to check the intersection - if(nextEntry.getTime() < finishTime) { - intersectList = PERangeList.intersection(intersectList, - nextEntry.getAvailRanges()); - } - } - - if(intersectList == null || intersectList.getNumPE() < reqPE) { - // there are not enough PEs available to serve the - // advance reservation request, then returns null - break; - } - } - } - } - - if(intersectList == null || intersectList.getNumPE() < reqPE) { - // there are not enough PEs available to serve the - // advance reservation request, then returns null - return false; - } - - return true; + double potStartTime = getPotentialStartTime(readyTime, duration, reqPE, deadline); + return potStartTime > UNKNOWN ? true : false; } /** @@ -403,57 +406,72 @@ LinkedList<TimeSlot> slots = new LinkedList<TimeSlot>(); // start time cannot be smaller than the start time of the info obj - if(startTime < startTime_) + if(startTime < startTime_) { startTime = startTime_; - + } // start time cannot be larger than the finish time of the info obj - if(startTime > finishTime_) { + else if(startTime > finishTime_) { return slots; } + + // the finish time cannot be larger than this object finish time + if(finishTime > finishTime_) { + finishTime = finishTime_; + } AvailabilityInfoEntry entry = getPrecedingEntry(startTime); AvailabilityInfoEntry nextEntry = null; PERangeList slotRanges = null; PERangeList intersect = null; int size = super.size(); + int firstIndex = super.indexOf(entry); - for(int i=super.indexOf(entry); i<size; i++) { + if(firstIndex < 0) + firstIndex = 0; + + for(int i=firstIndex; i<size; i++) { entry = super.get(i); + if(entry.getTime() >= finishTime) { break; } else if (entry.getNumPE() == 0) { continue; } - - double slotStart = - entry.getTime() < startTime ? startTime : entry.getTime(); + slotRanges = entry.getAvailRanges(); + double slotStart = Math.max(entry.getTime(), startTime); - for(int j=i; j<size; j++) { - nextEntry = super.get(j); - intersect = PERangeList.intersection(slotRanges, nextEntry.getAvailRanges()); - double endTime = entry.getTime(); - boolean different = !intersect.equals(slotRanges); - if(j < (size-1) && different) { - if((endTime - slotStart) >= duration && slotRanges.getNumPE() >= numPEs) { - TimeSlot slot = new TimeSlot(slotStart, endTime, slotRanges); - slots.add(slot); + do { + int initialPE = slotRanges.getNumPE(); + + for(int j=i+1; j<size; j++) { + nextEntry = super.get(j); + intersect = PERangeList.intersection(slotRanges, nextEntry.getAvailRanges()); + + // if there was a change in the number of PEs, so that less PEs are available + // after the next entry, then considers the next entry as the end of the + // current time slot + if(intersect == null || intersect.getNumPE() < slotRanges.getNumPE()) { + double endTime = Math.min(nextEntry.getTime(), finishTime); + if((endTime - slotStart) >= duration && slotRanges.getNumPE() >= numPEs) { + TimeSlot slot = new TimeSlot(slotStart, endTime, slotRanges.clone()); + slots.add(slot); + } + slotRanges = intersect; + break; } - slotRanges = intersect; } - else if (j == (size-1)) { - if((endTime - slotStart) >= duration && slotRanges.getNumPE() >= numPEs) { - TimeSlot slot = new TimeSlot(slotStart, finishTime, slotRanges); + + if(slotRanges != null && slotRanges.getNumPE() == initialPE) { + if((finishTime - slotStart) >= duration && slotRanges.getNumPE() >= numPEs) { + TimeSlot slot = new TimeSlot(slotStart, finishTime, slotRanges.clone()); slots.add(slot); } - continue; + slotRanges = null; } - if(intersect == null && intersect.getNumPE() == 0) { - break; - } - } + } while(slotRanges != null && slotRanges.getNumPE() > 0); } return slots; Modified: branches/gridsim4.0-branch3/source/gridsim/turbo/TimeSlot.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/turbo/TimeSlot.java 2008-06-13 00:55:20 UTC (rev 183) +++ branches/gridsim4.0-branch3/source/gridsim/turbo/TimeSlot.java 2008-06-17 07:21:14 UTC (rev 184) @@ -117,4 +117,13 @@ public int getNumPE() { return ranges_ == null ? 0 : ranges_.getNumPE(); } + + /** + * Creates a string representation of the list + * @return a string representation + */ + public String toString() { + return "TimeSlot={startTime=" + startTime_ + + ", finishTime=" + finishTime_ + ", ranges=" + ranges_ + "}"; + } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |