2008-03-05 09:52:00 -05:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
|
|
// Microsoft Research Singularity
|
|
|
|
//
|
|
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
|
|
//
|
|
|
|
// Note: Simple Singularity test program.
|
|
|
|
//
|
|
|
|
using System;
|
|
|
|
using System.Threading;
|
|
|
|
using Microsoft.Singularity.Channels;
|
|
|
|
|
|
|
|
using Microsoft.Contracts;
|
|
|
|
using Microsoft.SingSharp.Reflection;
|
|
|
|
using Microsoft.Singularity.Applications;
|
|
|
|
using Microsoft.Singularity.Io;
|
|
|
|
using Microsoft.Singularity.Configuration;
|
|
|
|
[assembly: Transform(typeof(ApplicationResourceTransform))]
|
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
namespace Microsoft.Singularity.Applications
|
|
|
|
{
|
2008-03-05 09:52:00 -05:00
|
|
|
[ConsoleCategory(DefaultAction=true)]
|
|
|
|
internal class Parameters {
|
|
|
|
[InputEndpoint("data")]
|
|
|
|
public readonly TRef<UnicodePipeContract.Exp:READY> Stdin;
|
|
|
|
|
|
|
|
[OutputEndpoint("data")]
|
|
|
|
public readonly TRef<UnicodePipeContract.Imp:READY> Stdout;
|
|
|
|
|
|
|
|
[LongParameter( "count", Position=0, Default=1000, HelpMessage="count")]
|
|
|
|
internal long count;
|
|
|
|
|
|
|
|
[BoolParameter( "a", Default=false, HelpMessage="Do Allocation")]
|
|
|
|
internal bool doAlloc;
|
|
|
|
|
|
|
|
[BoolParameter( "t", Default=false, HelpMessage="Do ThreadCount2 test")]
|
|
|
|
internal bool doThread2;
|
|
|
|
|
|
|
|
reflective internal Parameters();
|
|
|
|
|
|
|
|
internal int AppMain() {
|
|
|
|
return ChannelPerf.AppMain(this);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public class ChannelPerf
|
|
|
|
{
|
|
|
|
public contract ChannelPerfTest {
|
|
|
|
message Req(int x);
|
|
|
|
message Resp(int x);
|
|
|
|
|
|
|
|
state Start: Req? -> Resp! -> Start;
|
|
|
|
}
|
|
|
|
|
|
|
|
private static TRef<ChannelPerfTest.Exp:Start>! cpendpoint1;
|
|
|
|
private static TRef<ChannelPerfTest.Imp:Start>! cpendpoint2;
|
|
|
|
|
|
|
|
public static void ChannelPerfThread1()
|
|
|
|
{
|
|
|
|
ChannelPerfTest.Exp e1 = cpendpoint1.Acquire();
|
|
|
|
int arg;
|
|
|
|
|
|
|
|
while (true) {
|
|
|
|
e1.RecvReq(out arg);
|
|
|
|
if (arg == -1) break;
|
|
|
|
e1.SendResp(arg);
|
|
|
|
}
|
|
|
|
|
|
|
|
delete e1;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void ChannelPerfThread3( int count, bool doAlloc )
|
|
|
|
{
|
|
|
|
ChannelPerfTest.Imp e2 = cpendpoint2.Acquire();
|
|
|
|
int arg;
|
|
|
|
int num = count;
|
|
|
|
byte [] foo;
|
|
|
|
|
|
|
|
int collectorCountStart;
|
|
|
|
long collectorMillisStart, collectorBytesStart;
|
|
|
|
|
|
|
|
int collectorCountEnd;
|
|
|
|
long collectorMillisEnd, collectorBytesEnd;
|
|
|
|
|
|
|
|
Console.WriteLine("Sending/(switch) recving {0} messages ...", num);
|
|
|
|
if (doAlloc)
|
|
|
|
Console.WriteLine(" will do allocation ");
|
|
|
|
|
|
|
|
ulong before = Processor.CycleCount;
|
|
|
|
GC.PerformanceCounters(out collectorCountStart, out collectorMillisStart, out collectorBytesStart);
|
|
|
|
|
|
|
|
for (int i = 0; i < num; i++) {
|
|
|
|
arg = i;
|
|
|
|
e2.SendReq(arg);
|
2008-11-17 18:29:00 -05:00
|
|
|
switch receive {
|
2008-03-05 09:52:00 -05:00
|
|
|
case e2.Resp(reply):
|
2008-11-17 18:29:00 -05:00
|
|
|
if (doAlloc) {
|
2008-03-05 09:52:00 -05:00
|
|
|
foo = new byte[20000];
|
|
|
|
foo[1] = 0x3; // keep the compiler happy
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case e2.ChannelClosed():
|
|
|
|
throw new Exception("Didn't e2.Resp(arg)");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
GC.PerformanceCounters( out collectorCountEnd, out collectorMillisEnd, out collectorBytesEnd);
|
|
|
|
ulong after = Processor.CycleCount;
|
|
|
|
Console.WriteLine("Done sending messages ...");
|
|
|
|
e2.SendReq(-1);
|
|
|
|
delete e2;
|
|
|
|
Console.WriteLine("Elapsed cycles {0}", after - before);
|
|
|
|
Console.WriteLine("Cycles/RPC {0}", (after - before)/(ulong)num);
|
|
|
|
|
|
|
|
Console.WriteLine(" num GCs:{0}, milli={1}, bytes={2}\n",
|
|
|
|
(collectorCountEnd - collectorCountStart),
|
|
|
|
(collectorMillisEnd - collectorMillisStart),
|
|
|
|
(collectorBytesEnd - collectorBytesStart)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void ChannelPerfThread2()
|
|
|
|
{
|
|
|
|
ChannelPerfTest.Imp e2 = cpendpoint2.Acquire();
|
|
|
|
int arg;
|
|
|
|
const int num = 1000;
|
|
|
|
int collectorCountStart;
|
|
|
|
long collectorMillisStart, collectorBytesStart;
|
|
|
|
|
|
|
|
int collectorCountEnd;
|
|
|
|
long collectorMillisEnd, collectorBytesEnd;
|
|
|
|
|
|
|
|
Console.WriteLine("Sending/recving {0} messages ...", num);
|
|
|
|
GC.PerformanceCounters(out collectorCountStart, out collectorMillisStart, out collectorBytesStart);
|
|
|
|
|
|
|
|
Console.WriteLine(" Start: num GCs:{0}, milli={1}, bytes={2}\n",
|
|
|
|
collectorCountStart,
|
|
|
|
collectorMillisStart,
|
|
|
|
collectorBytesStart
|
|
|
|
);
|
|
|
|
|
|
|
|
ulong before = Processor.CycleCount;
|
|
|
|
for (int i = 0; i < num; i++) {
|
|
|
|
arg = i;
|
|
|
|
e2.SendReq(arg);
|
|
|
|
e2.RecvResp(out arg);
|
|
|
|
}
|
|
|
|
|
|
|
|
GC.PerformanceCounters( out collectorCountEnd, out collectorMillisEnd, out collectorBytesEnd);
|
|
|
|
|
|
|
|
ulong after = Processor.CycleCount;
|
|
|
|
Console.WriteLine("Done sending messages ...");
|
|
|
|
e2.SendReq(-1);
|
|
|
|
delete e2;
|
|
|
|
Console.WriteLine("Elapsed cycles {0}", after - before);
|
|
|
|
Console.WriteLine("Cycles/RPC {0}", (after - before)/num);
|
|
|
|
Console.WriteLine(" num GCs:{0}, milli={1}, bytes={2}\n",
|
|
|
|
(collectorCountEnd - collectorCountStart),
|
|
|
|
(collectorMillisEnd - collectorMillisStart),
|
|
|
|
(collectorBytesEnd - collectorBytesStart)
|
|
|
|
);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
//[ShellCommand("channelperf", "Measure channel performance")]
|
|
|
|
internal static int AppMain(Parameters! config)
|
|
|
|
{
|
|
|
|
|
|
|
|
bool doAlloc = config.doAlloc;
|
|
|
|
int count = (int) config.count;
|
|
|
|
|
|
|
|
// Make a new channel.
|
|
|
|
ChannelPerfTest.Imp! e2;
|
|
|
|
ChannelPerfTest.Exp! e1;
|
|
|
|
|
|
|
|
ChannelPerfTest.NewChannel(out e2, out e1);
|
|
|
|
|
|
|
|
// Endpoints are initially owned by the creating thread.
|
|
|
|
// We're going to transfer ownership to other threads, so
|
|
|
|
// we release them here.
|
|
|
|
cpendpoint1 = new TRef<ChannelPerfTest.Exp:Start>(e1);
|
|
|
|
cpendpoint2 = new TRef<ChannelPerfTest.Imp:Start>(e2);
|
|
|
|
|
|
|
|
// Create our two threads.
|
|
|
|
Thread t1 = new Thread(new ThreadStart(ChannelPerfThread1));
|
|
|
|
t1.Start();
|
|
|
|
|
|
|
|
//Thread t2 = new Thread(new ThreadStart(ChannelPerfThread2));
|
|
|
|
//t2.Start();
|
|
|
|
|
|
|
|
// Actually just call into Thread2 so we don't have to sit here
|
|
|
|
// twiddling our thumbs! :-)
|
|
|
|
|
|
|
|
if (config.doThread2) ChannelPerfThread2();
|
|
|
|
else ChannelPerfThread3(count,doAlloc);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|