Skip to main content

[faban-devel] Re: The @OnceBefore and @OnceAfter annotations

  • From: Yaomin Chen <yaomin.chen@...>
  • To: devel@...
  • Subject: [faban-devel] Re: The @OnceBefore and @OnceAfter annotations
  • Date: Sun, 15 May 2011 01:41:52 -0700

Yi Huang wrote:


On May 6, 2011, at 6:04 PM, Yaomin Chen wrote:

I learned that some benchmarks do use thread[0] of agent[0] for global initialization such as preparing a remote database.  So certainly there is need to preserve the existing behavior of @OnceBefore and @OnceAfter. 

We can look into a second set of annotations such as @OnceBeforePerAgent and @OnceAfterPerAgent as you described but there is an issue.  What if both @OnceBefore and @OnceBeforePerAgent are specified?

Sounds good.  We should also rename @OnceBefore to @OnceBeforePerRun (or something similar) to make its semantics clearer.

I did not change @OnceBefore and @OnceAfter since they are widely used in benchmarks.

I created @AgentInit (originally called @OnceBeforePerAgent) and @AgentFinal (originally called @OnceAfterPerAgent). I like the names to be shorter.



Which one gets to be executed first?

It should make sense to execute @OnceBeforePerRun first.
@OnceBefore is followed by @AgentInit.

@OnceAfter is preceded by @AgentFinal.

Yaomin


Right now, there is checking to see if a thread has global ID 0.  It it is such a thread, it needs to do the pre-run and post-run actions. The @OnceBeforePerAgent and @OnceAfterPerAgent annotations would require a thread to check if it is the first thread of its agent, so it can execute the pre-run-per-agent and post-run-per-agent actions. The thread ID checking leads to a somewhat hard-to-maintain code. 

I wonder if there is a Java language technique to allow us to still use the same @OnceBefore and @OnceAfter to annotate a method but within a method there is a block to be executed by agent[0] only and there is another block to be executed by all agents.

I do not think so.  Current Java annotation only supports methods level, not inside a method.

Cheers!

--Yi


Thought?

Yaomin


On 05/02/11 12:01, Yi Huang wrote:

To fill in this topic thread, I am using @OnceBefore and @OnceAfter in the driver side of a SIP benchmarking application.  My code assumes that the annotations be called for each agent, not the whole run.  But I can imagine it would be useful to have two sets of annotations each using for one of the two cases.  So

(1) @OnceBeforeRun and @OnceAfterRun would be called once for each run
(2) @OnceBeforeAgent and @OnceAfterAgent would be called once for each agent

However, if no one is using case (1) at this moment, we probably do not have to materialize (1) right now.  But it would still be a good idea to change the name @OnceBefore to @OnceBeforeAgent (likewise @OnceAfter) for clarification purpose and for ease of introducing @OnceBeforeRun in the future.

Best,

--Yi

On May 2, 2011, at 1:00 AM, Yaomin Chen wrote:

Yi found out that they were only executed by Thread 0 of Agent 0, which means, when there are multiple clients, the pre- and post-processing are only executed on the first client (that hosts agent 0).  Is this the expected behavior, or should we fix such that the @OnceBefore (@OnceAfter) annotated method is executed on every client?  Does anyone know a benchmark that uses the annotation?

In MasterImple.java, the thread IDs for each agent are manipulated so that they are non-overlapping among the agents.  Therefore, only Agent 0 runs Thread 0.

    578     private void configureAgents(int driverType) throws Exception {
    579
    580         int agentCnt = runInfo.driverConfigs[driverType].numAgents;
    581         if (agentCnt > 0) {
    582             RunInfo.AgentInfo agentInfo = new RunInfo.AgentInfo();
    583             runInfo.agentInfo = agentInfo;
    584             logger.config("num" + benchDef.drivers[driverType].name +
    585                         "Agents = " + agentCnt);
    586
    587             agentInfo.threads = agentThreads[driverType];
    588             agentInfo.agentScale = (double) runInfo.scale/agentCnt;
    589             Agent[] refs = agentRefs[driverType];
    590             logger.info("Configuring " + refs.length + ' ' +
    591                         benchDef.drivers[driverType].name + "Agents...");
    592
    593             runInfo.driverConfig = runInfo.driverConfigs[driverType];
    594             int agentId = 0;
    595
    596             // If there are remaining threads left, distribute each to
    597             // the first agents. Ditto for scale
    598             if (remainderThreads[driverType] > 0) {
    599                 agentInfo.threads = agentThreads[driverType] + 1;
    600                 agentInfo.agentScale = (double) runInfo.scale *
    601                         runInfo.driverConfigs[driverType].numThreads /
    602                         agentInfo.threads;
    603
    604                 for (; agentId < remainderThreads[driverType]; agentId++) {
    605                     runInfo.agentInfo.agentNumber = agentId;
    606                     refs[agentId].configure(this, runInfo, driverType, timer);
    607                     runInfo.agentInfo.startThreadNumber += agentInfo.threads;
    608                 }
    609             }
    610
    611             // Now deal with the non-remainders...
    612             agentInfo.threads = agentThreads[driverType];
    613             agentInfo.agentScale = (double) runInfo.scale *
    614                     runInfo.driverConfigs[driverType].numThreads /
    615                     agentInfo.threads;
    616
    617             for (; agentId < refs.length && !runAborted; agentId++) {
    618                 runInfo.agentInfo.agentNumber = agentId;
    619                 refs[agentId].configure(this, runInfo, driverType, timer);
    620                 runInfo.agentInfo.startThreadNumber += agentInfo.threads;
    621             }
    622         }
    623         runInfo.driverConfig = null;
    624         runInfo.agentInfo = null; // reset it so we don't use it anywhere else
    625     }

But in AgentThread.java:

    341     void preRun() {
    342         // Thread 0 needs to do the preRun
    343         if (id == 0 && driverConfig.preRun != null) {
    344             setThreadState(RunState.PRE_RUN);
    345             logger.fine(name + ": Invoking preRun @OnceBefore");
    346             try {
    347                 invokePrePost(driverConfig.preRun.m);
    348             } catch (InterruptedIOException e) {
    349                 // Should not happen unless run is cancelled. And if so,
    350                 // we don't really care to redo this.
    351             } finally {
    352                 agent.preRunLatch.countDown();
    353             }
    354             try {
    355                 while (!stopped) {
    356                     if (agent.startLatch.await(500, TimeUnit.MILLISECONDS))
    357                         break;
    358                 }
    359             } catch (InterruptedException e) {
    360                 logger.log(Level.WARNING, name +
    361                         ": Start latch await interrupted!");
    362             }
    363             agent.startLatch = null;
    364             logger.finest(name + ": Thread 0 got startLatch, now executing.");
    365         }
    366         setThreadState(RunState.RUNNING);
    367     }







[faban-devel] The @OnceBefore and @OnceAfter annotations

Yaomin Chen 05/02/2011

[faban-devel] Re: The @OnceBefore and @OnceAfter annotations

Yi Huang 05/02/2011

[faban-devel] Re: The @OnceBefore and @OnceAfter annotations

Yaomin Chen 05/07/2011

[faban-devel] Re: The @OnceBefore and @OnceAfter annotations

Yi Huang 05/07/2011

[faban-devel] Re: The @OnceBefore and @OnceAfter annotations

Yaomin Chen 05/15/2011
 
 
Close
loading
Please Confirm
Close