71
Curso de NS Rainer R. P. Couto ([email protected] )

Curso de NS Rainer R. P. Couto ([email protected])[email protected]

Embed Size (px)

Citation preview

Page 1: Curso de NS Rainer R. P. Couto (rainerpc@dcc.ufmg.br)rainerpc@dcc.ufmg.br

Curso de NS

Rainer R. P. Couto([email protected])

Page 2: Curso de NS Rainer R. P. Couto (rainerpc@dcc.ufmg.br)rainerpc@dcc.ufmg.br

Sumário

Arquitetura do Software Hierarquia de Objetos Principais Classes em OTcl e C++

Escalonador Temporizadores – Timers Geração de números aleatórios

Page 3: Curso de NS Rainer R. P. Couto (rainerpc@dcc.ufmg.br)rainerpc@dcc.ufmg.br

Arquitetura do software

Page 4: Curso de NS Rainer R. P. Couto (rainerpc@dcc.ufmg.br)rainerpc@dcc.ufmg.br

Arquitetura do Software Tcl

“script language” Fracamente tipada Configuração

C/C++ “system language” Fortemente tipada “Core programming”

OTcl Tcl orientado a objetos

TclCL (TclCLass) Tcl com suporte a “object

oriented split-level programming”

Tcl

OTcl

TclCL

ns-2

Esca

lonad

or

de e

ven

tos

Componentesde rede

C/C++

Page 5: Curso de NS Rainer R. P. Couto (rainerpc@dcc.ufmg.br)rainerpc@dcc.ufmg.br

Estrutura Interna

Arquitetura do NS Orientado a objetos Escrito em C++ Interpretador Tcl

como frontend

Arquitetura do NS Duas hierarquias de

objetos Hierarquia C++

(compilada) Hierarquia OTcl

(interpretada) Correspodência um para

um pela perspectiva do usuário

C++ OTcl

Pure C++objects

Pure OTclobjects

C++/OTcl split objects

ns

Page 6: Curso de NS Rainer R. P. Couto (rainerpc@dcc.ufmg.br)rainerpc@dcc.ufmg.br

Split-level programming Por que duas linguagens?

C++: execução rápida / alteração complexa Processamento de cada pacote, alteração de

comportamento de objetos existentes em C++ (“dado”), estruturas e algotirmos complexos, código com alterações infreqüentes

OTcl: alteração simples / execução lenta Configuração, setup, escalonamento de eventos periódicos e

manipulação simples de objetos (“controle”), código com alterações freqüentes

Tclcl provê a forma de unir as duas linguagens

+ Compromisso entre composabilidade e velocidade– Aprendizado e correção de erros

Page 7: Curso de NS Rainer R. P. Couto (rainerpc@dcc.ufmg.br)rainerpc@dcc.ufmg.br

O Mérito do OTcl

Granularidade do código/script pode ser ajustada para compensar extensibilidade por performance.

Tamanho do programacomplexidade

C/C++

OTcl

grande pequeno

split objects

1000

100

10

1

Inst

ruct

ion

s/S

tate

men

t

None Strong Degree of Typing

Assembly C++C

Java

Tcl/Perl

Visual Basic

John Ousterhout. Scripting: Higher-level programming for the 21st centuryIEEE Computer, 1998.

Page 8: Curso de NS Rainer R. P. Couto (rainerpc@dcc.ufmg.br)rainerpc@dcc.ufmg.br

Principais classes da programação C++/OTcl

bind(): realiza o “link” dos valores das variáveis compartilhadas entre C++ e OTcl TclObjectcommand(): realiza o “link” entre métodos chamados no OTcl e implementados em C++

TclClass Cria e inicializa TclObject’s

Tcl Métodos C++ para acessar o interpretador Tcl

TclCommand Comandos globais

EmbeddedTcl Inicialização do script ns

Raiz da hierarquia de objetos do ns-2

Page 9: Curso de NS Rainer R. P. Couto (rainerpc@dcc.ufmg.br)rainerpc@dcc.ufmg.br

Principais classes da programação C++/OTcl

bind(): realiza o “link” dos valores das variáveis compartilhadas entre C++ e OTcl TclObjectcommand(): realiza o “link” entre métodos chamados no OTcl e implementados em C++

TclClass Cria e inicializa TclObject’s

Tcl Métodos C++ para acessar o interpretador Tcl

TclCommand Comandos globais

EmbeddedTcl Inicialização do script ns

Raiz da hierarquia de objetos do ns-2

Page 10: Curso de NS Rainer R. P. Couto (rainerpc@dcc.ufmg.br)rainerpc@dcc.ufmg.br

TclObject: Hierarquia e Shadowing

TclObject

Agent

Agent/TCP

Agent/TCP OTcl Objeto shadow

_o123Objeto

Agent/TCP C++

*tcp

TclObject

Agent

TcpAgent

Hierarquia declasses OTcl

Hierarquia declasses C++

Page 11: Curso de NS Rainer R. P. Couto (rainerpc@dcc.ufmg.br)rainerpc@dcc.ufmg.br

TclObject::bind() “Une” variáveis membras de classes no C++ a variáveis

no OTcl Duas referências para um mesmo objeto

C++TcpAgent::TcpAgent() {TcpAgent::TcpAgent() {

bind(“bind(“window_window_”, &wnd_);”, &wnd_);bind_bw(“bind_bw(“taxataxa__", &", &taxataxa_);_);

}} bind_time(), bind_bool(), bind_bw()

OTclset tcp [new Agent/TCP]set tcp [new Agent/TCP]$tcp set window_ 200$tcp set window_ 200$tcp set taxa_ 1.5Mb$tcp set taxa_ 1.5Mb

Page 12: Curso de NS Rainer R. P. Couto (rainerpc@dcc.ufmg.br)rainerpc@dcc.ufmg.br

Inicialização de variáveis do “bind”

Inicialização através de variáveis de classe do OTclAgent/TCP set Agent/TCP set window_window_ 50 50

Faça toda a inicialização de variáveis de “bind” em ~ns/tcl/lib/ns-default.tcl

Caso contrário, um aviso de alerta será mostrado quando o objeto “shadow” for criado

Page 13: Curso de NS Rainer R. P. Couto (rainerpc@dcc.ufmg.br)rainerpc@dcc.ufmg.br

Implementação de variáveis de “bind”

Classe InstVar Um objeto por variável de “bind” – caro! InstVarInt, InstVarReal, ...

Criados por TclObject::bind() Cria instância da variável na pilha OTcl Habilita “trap” de escrita/leitura para variável OTcl Conecta à variável C++ na ocorrência de “traps”

Page 14: Curso de NS Rainer R. P. Couto (rainerpc@dcc.ufmg.br)rainerpc@dcc.ufmg.br

TclObject::command()

Implementa métodos do OTcl em C++ “Trap point”: Método cmd{} em OTcl

Após chamado, cmd{} envia todos seus argumentos para TclObject::command()

Page 15: Curso de NS Rainer R. P. Couto (rainerpc@dcc.ufmg.br)rainerpc@dcc.ufmg.br

TclObject::command() OTcl

set tcp [new Agent/TCP]$tcp advance 10

C++int TcpAgent::command(int argc,

const char*const* argv) { if (argc == 3) {

if (strcmp(argv[1], “advance”) == 0) { int newseq = atoi(argv[2]);

…… return(TCL_OK);

} }

return (Agent::command(argc, argv);}

Page 16: Curso de NS Rainer R. P. Couto (rainerpc@dcc.ufmg.br)rainerpc@dcc.ufmg.br

TclObject::command()

$tcp send TclObject::unknown{} $tcp cmd sendprocedimentonão existe

TcpAgent::command()

implementa “send”?

Chama o método do pai: return Agent::command()

Processa e retorna

Sim Não

OTcl space

C++ space

Page 17: Curso de NS Rainer R. P. Couto (rainerpc@dcc.ufmg.br)rainerpc@dcc.ufmg.br

TclObject: Criação e Remoção

Procedimentos globais: new{}, delete{} Exemplo

set tcp [set tcp [newnew Agent/TCP] Agent/TCP]

……

deletedelete $tcp $tcp

Page 18: Curso de NS Rainer R. P. Couto (rainerpc@dcc.ufmg.br)rainerpc@dcc.ufmg.br

TclObject: Criação e Remoção

C++

OTcl

chama cons_trutor do pai

construtorAgent/TCP

construtorpai (Agent)

chama cons_trutor do pai

construtorTclObject

cria objeto C++

construtorAgentTCP

chama cons_trutor do pai

chama cons_trutor do pai

construtor pai (Agent)

Não faz nada,retorna

construtorTclObject (C++)

realiza bindse retorna

realiza bindse retorna

cria objeto shadow OTcl

completainicialização

completainicialização

Qual objeto C++deve ser criado? – TclClass

Page 19: Curso de NS Rainer R. P. Couto (rainerpc@dcc.ufmg.br)rainerpc@dcc.ufmg.br

Principais classes da programação C++/OTcl

TclClass Cria e inicializa TclObject’s

Tcl Métodos C++ para acessar o interpretador Tcl

TclCommand Comandos globais

EmbeddedTcl Inicialização do script ns

bind(): realiza o “link” dos valores das variáveis compartilhadas entre C++ e OTcl TclObjectcommand(): realiza o “link” entre métodos chamados no OTcl e implementados em C++

Raiz da hierarquia de objetos do ns-2

Page 20: Curso de NS Rainer R. P. Couto (rainerpc@dcc.ufmg.br)rainerpc@dcc.ufmg.br

TclClass

TclObject

Agent

Agent/TCP

TclObject

Agent

TcpAgent

NsObject ??

OTclC++ Static class TcpClass : public TclClass {public:

TcpClass() : TclClass(“Agent/TCP”) {}TclObject* create(int, const char*const*) {

return (new TcpAgent());}

} class_tcp;

Static class TcpClass : public TclClass {public:

TcpClass() : TclClass(“Agent/TCP”) {}TclObject* create(int, const char*const*) {

return (new TcpAgent());}

} class_tcp;

Page 21: Curso de NS Rainer R. P. Couto (rainerpc@dcc.ufmg.br)rainerpc@dcc.ufmg.br

TclClass: Mecanismo

Inicialização durante o “startup” da execução

SplitObject::register{} Cria e registra

Classe OTcl Agent/TCP

TclClass::init()

para cada TclClassdefinida estaticamente

TcpClass::bind()

e.g.

Agent/TCP::create-shadow{} TclClass::create_shadow()

Page 22: Curso de NS Rainer R. P. Couto (rainerpc@dcc.ufmg.br)rainerpc@dcc.ufmg.br

Principais classes da programação C++/OTcl

bind(): realiza o “link” dos valores das variáveis compartilhadas entre C++ e OTcl TclObjectcommand(): realiza o “link” entre métodos chamados no OTcl e implementados em C++

TclClass Cria e inicializa TclObject’s

Tcl Métodos C++ para acessar o interpretador Tcl

TclCommand Comandos globais

EmbeddedTcl Inicialização do script ns

Raiz da hierarquia de objetos do ns-2

Page 23: Curso de NS Rainer R. P. Couto (rainerpc@dcc.ufmg.br)rainerpc@dcc.ufmg.br

Classe Tcl

Classe que possui a referência para o interpretador Tcl

Uso Chamar procedimentos em OTcl Obter resultados de expressões em OTcl Passar um resultado para o OTcl Retornar um código de sucesso/falha para o Otcl Armazenar e realizar procuras por referências a

TclObjects

Page 24: Curso de NS Rainer R. P. Couto (rainerpc@dcc.ufmg.br)rainerpc@dcc.ufmg.br

Obtendo uma referência para o interpretador

Uma única referência ao intepretador está declarado no arquivo Tcl.cc (dentro do diretório tclclXXX) como um membro estático da classe Tcl. Antes de acessar qualquer método do intepretador, devemos obter essa referência.

Comando

Tcl& tcl = Tcl::instance();Tcl& tcl = Tcl::instance();

Page 25: Curso de NS Rainer R. P. Couto (rainerpc@dcc.ufmg.br)rainerpc@dcc.ufmg.br

Passandos comandos para o interpretador

Tcl& tcl = Tcl::instance(); Tcl& tcl = Tcl::instance();

char wrk[128];char wrk[128];

strcpy(wrk, "Simulator set NumberInterfaces_ 1"); strcpy(wrk, "Simulator set NumberInterfaces_ 1");

tcl.eval(wrk); tcl.eval(wrk);

sprintf(tcl.buffer(), "Agent/SRM set requestFunction_ %s",sprintf(tcl.buffer(), "Agent/SRM set requestFunction_ %s", "Fixed"); "Fixed");

tcl.eval(); tcl.eval();

tcl.evalc("puts stdout tcl.evalc("puts stdout \”\”hello worldhello world\”\”"); ");

tcl.evalf("%s request %d %d", name_, sender, msgid); tcl.evalf("%s request %d %d", name_, sender, msgid);

Tcl::eval(char *): passa string para o intepretador Tcl::evalc(const char *): preserva o string de entrada Tcl::eval(): supõe que o comando já está em tcl.buffer Tcl::evalf(char *, par1, par2, ...): “printf like” Exemplo:

Page 26: Curso de NS Rainer R. P. Couto (rainerpc@dcc.ufmg.br)rainerpc@dcc.ufmg.br

Coletando resultados

Quanto o intepretador chama um comando em C++, espera-se um resultado na variável interna result.

Comando: tcl.resultf()

Similarmente, quando o C++ faz uma chamada a um método do interpretador, o resultado pode ser acessado através da mesma variável.

Comando: tcl.result()

Page 27: Curso de NS Rainer R. P. Couto (rainerpc@dcc.ufmg.br)rainerpc@dcc.ufmg.br

Exemplo de métodos de Tcl

Tcl& tcl = Tcl::instance();if (argc == 2) {

if (strcmp(argv[1], “now”) == 0) {tcl.resultf(“%g”, clock());return TCL_OK;

}tcl.error(“command not found”);return TCL_ERROR;

} else if (argc == 3) {tcl.eval(argv[2]);clock_ = atof(tcl.result());return TCL_OK;

}

Page 28: Curso de NS Rainer R. P. Couto (rainerpc@dcc.ufmg.br)rainerpc@dcc.ufmg.br

Funções de Hash da classe Tcl

O intepretador possui uma tabela hash com entradas para todos TclObjects criados durante a simulação.

void Tcl::enter(TclObject* o) Utilizado para criar uma nova entrada para o novo

TclObject

TclObject* Tcl::lookup(const char* name) Utilizado para fazer uma procura por um TclObject

Page 29: Curso de NS Rainer R. P. Couto (rainerpc@dcc.ufmg.br)rainerpc@dcc.ufmg.br

Principais classes da programação C++/OTcl

bind(): realiza o “link” dos valores das variáveis compartilhadas entre C++ e OTcl TclObjectcommand(): realiza o “link” entre métodos chamados no OTcl e implementados em C++

TclClass Cria e inicializa TclObject’s

Tcl Métodos C++ para acessar o interpretador Tcl

TclCommand Comandos globais

EmbeddedTcl Inicialização do script ns

Raiz da hierarquia de objetos do ns-2

Page 30: Curso de NS Rainer R. P. Couto (rainerpc@dcc.ufmg.br)rainerpc@dcc.ufmg.br

Class TclCommand Implementação em C++ de comandos globais em OTcl

class RandomCommand : public TclCommand {public: RandomCommand() : TclCommand("ns-random") {} virtual int command(int argc, const char*const* argv);};

int RandomCommand::command(int argc, const char*const* argv){ Tcl& tcl = Tcl::instance(); if (argc == 1) { ... }} Inicializar um novo objeto – new RandomCommand() – em

misc.cc::init_misc

Page 31: Curso de NS Rainer R. P. Couto (rainerpc@dcc.ufmg.br)rainerpc@dcc.ufmg.br

Principais classes da programação C++/OTcl

bind(): realiza o “link” dos valores das variáveis compartilhadas entre C++ e OTcl TclObjectcommand(): realiza o “link” entre métodos chamados no OTcl e implementados em C++

TclClass Cria e inicializa TclObject’s

Tcl Métodos C++ para acessar o interpretador Tcl

TclCommand Comandos globais

EmbeddedTcl Inicialização do script ns

Raiz da hierarquia de objetos do ns-2

Page 32: Curso de NS Rainer R. P. Couto (rainerpc@dcc.ufmg.br)rainerpc@dcc.ufmg.br

EmbeddedTcl Carrega OTcl scripts durante a inicialização do ns

Carrega recursivamente ~ns/tcl/lib/ns-lib.tcl:~ns/tcl/lib/ns-lib.tcl:source ns-autoconf.tclsource ns-autoconf.tclsource ns-address.tclsource ns-address.tclsource ns-node.tclsource ns-node.tcl....... .......

Carrega tudo em um único vetor de caracteres em C++ Executa esse string durante a inicialização

Page 33: Curso de NS Rainer R. P. Couto (rainerpc@dcc.ufmg.br)rainerpc@dcc.ufmg.br

EmbeddedTcl

Como funciona tcl2c++tcl2c++: provido pelo TclCL, converte tcl scripts em

vetores estáticos de caracteres em C++ Makefile.in:

tclsh8.0 bin/tcl-expand.tcl tcl/lib/ns-lib.tcl tclsh8.0 bin/tcl-expand.tcl tcl/lib/ns-lib.tcl | tcl2c++ et_ns_lib > gen/ns_tcl.cc| tcl2c++ et_ns_lib > gen/ns_tcl.cc

Page 34: Curso de NS Rainer R. P. Couto (rainerpc@dcc.ufmg.br)rainerpc@dcc.ufmg.br

Resumo TclObject

Classe raiz das hierarquias compilada (C++) e interpretada (OTcl)

Acesso transparente (chamadas de procedimento e acesso de variáveis) entre OTcl e C++

TclClass Mecanismo que torna possível TclObject

Tcl Primitivas para acessar o interpretador Tcl

Page 35: Curso de NS Rainer R. P. Couto (rainerpc@dcc.ufmg.br)rainerpc@dcc.ufmg.br

Escalonador

Page 36: Curso de NS Rainer R. P. Couto (rainerpc@dcc.ufmg.br)rainerpc@dcc.ufmg.br

Utilizando-se o NS... Criação do simulador

Escalonador de eventos

[Habilitação do tracing] Criação da rede Configuração do roteamento ...

set ns [new Simulator]set ns [new Simulator]

# [Turn on tracing]# [Turn on tracing]

# Create topology# Create topology

# Setup packet loss, link # Setup packet loss, link dynamicsdynamics

# Create routing agents# Create routing agents

# Create: # Create:

# - multicast groups# - multicast groups

# - protocol agents# - protocol agents

# - application and/or setup # - application and/or setup traffic sourcestraffic sources

# Post-processing procs# Post-processing procs

# Start simulation# Start simulation

Page 37: Curso de NS Rainer R. P. Couto (rainerpc@dcc.ufmg.br)rainerpc@dcc.ufmg.br

Escalonador

O que é o escalonador? Controlador de eventos dentro do simulador

Arquivos correspondentes: tcl/lib/ns-lib.tcl (class Simulator) common/scheduler(.h,.cc) (class Scheduler) heap.h (class Heap)

Page 38: Curso de NS Rainer R. P. Couto (rainerpc@dcc.ufmg.br)rainerpc@dcc.ufmg.br

Modelo do escalonador

Modela mundo como eventos Simulador possui uma lista de eventos Processo: pega o primeiro evento da lista, executa

até estar completo Cada evento acontece em um determinado instante

do tempo virtual (tempo simulado), mas pode levar um tempo real arbitrátio

Implementação muito simples uma thread de controle => não precisamos nos

preocupar com condições de corrida ou “locking” (bem simples)

Page 39: Curso de NS Rainer R. P. Couto (rainerpc@dcc.ufmg.br)rainerpc@dcc.ufmg.br

Escalonador de Eventos

time_, uid_, next_, handler_

handler_ -> handle()

time_, uid_, next_, handler_insert

head_ ->

class Event {public: Event* next_; /* event list */ Handler* handler_; /* handler to call when event ready */ double time_; /* time at which event is ready */ scheduler_uid_t uid_; /* unique ID */ Event() : time_(0), uid_(0) {}};

class Handler { public: virtual void handle(Event* event) = 0;};

Page 40: Curso de NS Rainer R. P. Couto (rainerpc@dcc.ufmg.br)rainerpc@dcc.ufmg.br

Modelo do escalonador

Considere dois nodosem uma rede Ethernet

A B

Modelo de filas simplificado:t=1 A coloca um pacote na fila da LANt=1.01 LAN retira o pacote da fila e LAN e

dispara um evento de recepção em B

Modelo CSMA/CD detalhado:

t=1.0 A envia pacote para NIC; NIC de A inicia “carrier sense”

t=1.005 NIC de A conclui cs, inicia txt=1.006 NIC de B começa a recepção do pacotet=1.01 NIC de B conclui recepção do pacote

NIC de B passa pacote para agente/aplicação

Page 41: Curso de NS Rainer R. P. Couto (rainerpc@dcc.ufmg.br)rainerpc@dcc.ufmg.br

Criação do escalonador Criação do simulador de eventos

set ns [new Simulator] Escalonamento de eventos

$ns at <tempo> <evento> <evento>: qualquer comando legítimo no ns/tcl Ex: $ns at 5.0 “finish”

Início da execução do escalonador$ns run

Escalonador Calendar: default Escalonador Real-time

Sincroniza com tempo real Emulação de redes

set ns_ [new Simulator]set ns_ [new Simulator]$ns_ use-scheduler Heap$ns_ use-scheduler Heap$ns_ at 300.5 “$self halt”$ns_ at 300.5 “$self halt”

Page 42: Curso de NS Rainer R. P. Couto (rainerpc@dcc.ufmg.br)rainerpc@dcc.ufmg.br

Simulador - métodosSimulator instproc init args {Simulator instproc init args {

$self instvar useasim_$self instvar useasim_

......__

set slinks_(0:0) 0set slinks_(0:0) 0

......

$self create_packetformat$self create_packetformat

$self use-scheduler Calendar$self use-scheduler Calendar

#$self use-scheduler List#$self use-scheduler List

......

}}

Simulator instproc use-scheduler type {Simulator instproc use-scheduler type {

$self instvar scheduler_$self instvar scheduler_

if [info exists scheduler_] {if [info exists scheduler_] {

if { [$scheduler_if { [$scheduler_ info class] == info class] ==

"Scheduler/$type" } {"Scheduler/$type" } {

returnreturn

} else {} else {

delete $scheduler_delete $scheduler_

}}

}}

set scheduler_ [newset scheduler_ [new Scheduler/$type]Scheduler/$type]

$scheduler_$scheduler_ nownow

}}Simulator instproc at args {Simulator instproc at args {

$self instvar scheduler_$self instvar scheduler_

return [eval $scheduler_ at $args]return [eval $scheduler_ at $args]

}}

Simulator instproc run {} {Simulator instproc run {} {

......

return [$scheduler_ run]return [$scheduler_ run]

}}

Page 43: Curso de NS Rainer R. P. Couto (rainerpc@dcc.ufmg.br)rainerpc@dcc.ufmg.br

Escalonador - Tipos

ListScheduler Lista simples O(N)

HeapScheduler Baseado em um

Heap O(logN)

CalendarScheduler Baseado em Hash

O(1) SplayScheduler RealTimerScheduler

Page 44: Curso de NS Rainer R. P. Couto (rainerpc@dcc.ufmg.br)rainerpc@dcc.ufmg.br

Modos do escalonadorModo interativo

arara:/ns-> ns

% set ns [new Simulator]

_o3

% $ns at 1 “puts \“Hello World!\””

1

% $ns at 1.5 “exit”

2

% $ns run

Hello World!

arara:/ns->

Modo batch:

simple.tcl

set ns [new Simulator]

$ns at 1 “puts \“Hello World!\””

$ns at 1.5 “exit”

$ns run

arara:/ns-> ns simple.tcl

Hello World!

arara:/ns->

Page 45: Curso de NS Rainer R. P. Couto (rainerpc@dcc.ufmg.br)rainerpc@dcc.ufmg.br

Temporizadores – Timers

Page 46: Curso de NS Rainer R. P. Couto (rainerpc@dcc.ufmg.br)rainerpc@dcc.ufmg.br

Temporizadores – Timers O que é um temporizador?

Um temporizador (timer) é um elemento que dispara um determinado evento e que pode ser programado

Usado principalmente em agentes, mas pode ser utilizado em outros objetos

Ex: retransmissão no agente TCP

Temporizadores podem ser implementados em C++ ou em OTcl.

São baseados em uma classe abstrata definida em timer-handler.h

Em OTcl um temporizador pode ser criado derivando a classe definida em tcl/mcast/timer.tcl.

Page 47: Curso de NS Rainer R. P. Couto (rainerpc@dcc.ufmg.br)rainerpc@dcc.ufmg.br

Temporizadores – Funções e atributos

A classe abstrata TimerHandler contém os seguintes métodos públicos disponíveis:

void sched(double delay) Escalona um temporizador para disparar em “delay”

segundos void resched(double delay)

Re-escalona o temporizador (similar ao sched, mas o temporizador pode estar pendente)

void cancel() Cancela um temporizador pendente

int status() Retorna o status do temporizador (TIMER_IDLE,

TIMER_PENDING, ou TIMER_HANDLING)

Page 48: Curso de NS Rainer R. P. Couto (rainerpc@dcc.ufmg.br)rainerpc@dcc.ufmg.br

Temporizadores – Funções e atributos

A classe abstrata TimerHandler contém os seguintes métodos protegidos disponíveis:

virtual void expire (Event* e) = 0 Este método deve ser preenchido com o código a ser

executado no instante de disparo do evento virtual void handle (Event* e)

Consome um evento; faz um chamada para expire() e atribui o valor adequado a status_

int status_ Variável que mantém o atual status do temporizador

Event event_ Evento que deve ser consumido

Page 49: Curso de NS Rainer R. P. Couto (rainerpc@dcc.ufmg.br)rainerpc@dcc.ufmg.br

Temporizadores – Funções e atributos

O método virtual expire() deve ser defindo na classe derivada da classe abstrata

Dois métodos privados “inline” são definidos: inline void _sched(double delay)

{ (void)Scheduler::instance().schedule(this, &event_, delay); }

inline void _cancel() { (void)Scheduler::instance().cancel(&event_); }

Esses códigos utilizam diretamente métodos do escalonador.

Page 50: Curso de NS Rainer R. P. Couto (rainerpc@dcc.ufmg.br)rainerpc@dcc.ufmg.br

Definindo um Temporizador

Temporizadores criados em C++ não são diretamente acessíveis através do Otcl.

Geralmente um temporizador será uma classe amiga da classe agente onde se encontra ou expire() chamará um método público deste agente.

class MyTimer : public TimerHandler { public: MyTimer(MyAgentClass *a) : TimerHandler() { a_ = a; } virtual double expire(Event *e); protected: MyAgentClass *a_; };

double MyTimer::expire(Event *e) {

// executa a função // Opção 1: // =\> não re-escalona o temporizador // Opção 2: // =\> re-escalona temporizador para // =\> disparar novamente em “delay” // =\> segundos }

Page 51: Curso de NS Rainer R. P. Couto (rainerpc@dcc.ufmg.br)rainerpc@dcc.ufmg.br

Exemplo – Retransmissão no TCP

Existem três temporizadores declarados no agente TCP Tahoe definido em tcp.cc:

rtx_timer_; Temporizador de retransmissão

delsnd_timer_; Atrasa o envio do pacote por um pequeno tempo aleatório, de

forma a evitar efeitos cíclicos burstsnd_timer_;

Auxilia o TCP no envio de uma grande janela de tranmissão dividida em várias partes menores

Em tcp.h existem três classes de temporizadores definidas:

class RtxTimer class DelSndTimer class BurstSndTimer

class RtxTimer : public TimerHandler { public: RtxTimer(TcpAgent *a) : TimerHandler() { a_ = a; } protected: virtual void expire(Event *e); TcpAgent *a_; };

Page 52: Curso de NS Rainer R. P. Couto (rainerpc@dcc.ufmg.br)rainerpc@dcc.ufmg.br

Exemplo – Retransmissão no TCP

TcpAgent::TcpAgent() : Agent(PT_TCP), rtt_active_(0), rtt_seq_(-1), ... rtx_timer_(this), delsnd_timer_(this), burstsnd_timer_(this) { ... }

void TcpAgent::set_rtx_timer() { rtx_timer_.resched(rtt_timeout()); }

void TcpAgent::newtimer (Packet* pkt) { hdr_tcp *tcph = (hdr_tcp*) pkt->access( off_tcp_ ); if ( t_seqno_ > tcph->seqno() ) set_rtx_timer(); else if ( rtx_timer_.status() == TIMER_PENDING ) rtx_timer_.cancel(); }

void TcpAgent::timeout( int tno ) { ... }

void RtxTimer::expire( Event *e ) { a_->timeout( TCP_TIMER_RTX ); }

Page 53: Curso de NS Rainer R. P. Couto (rainerpc@dcc.ufmg.br)rainerpc@dcc.ufmg.br

Temporizador em OTcl

Diferença básica: ao contrário da implementação em C++, onde uma chamada a sched() para um temporizador pendente causa um abort(), sched e resched em OTcl possuem a mesma funcionalidade

Nenhum estado é mantido para o temporizador

As seguintes funções são definidas para o temporizador: $self sched $delay # programa o temporizador para $delay

seg.; $self resched $delay # o memo que "$self sched $delay" ; $self cancel # cancela o temporizador (não há callback); $self destroy # o mesmo que "$self cancel"; $self expire # faz uma chamada a "$self timeout"

imediatamente; “timeout” deve estar definida na subclasse

/tcl/mcast/timer.tcl:...Timer instproc sched delay { $self instvar ns_ $self instvar id_ $self cancel set id_ [$ns_ after $delay "$self timeout"]}...

Page 54: Curso de NS Rainer R. P. Couto (rainerpc@dcc.ufmg.br)rainerpc@dcc.ufmg.br

Geração de Números Aleatórios

Page 55: Curso de NS Rainer R. P. Couto (rainerpc@dcc.ufmg.br)rainerpc@dcc.ufmg.br

Geração de Números Aleatórios

Suporte Matemático. O NS possui uma pequena coleção de funções

matemáticas usadas para implementar funções geradoras de números aleatórios e cálculos de integrais.

Os procedimentos podem ser encontrados nos seguintes arquivos:

tools/rng.{cc, h}. tools/random.{cc, h}. tools/ranvar.{cc, h}. tools/pareto.{cc, h}. tools/expoo.{cc, h}. tools/integrator.{cc, h}. tcl/lib/ns-random.tcl.

Page 56: Curso de NS Rainer R. P. Couto (rainerpc@dcc.ufmg.br)rainerpc@dcc.ufmg.br

Geração de números aleatórios

A classe RNG possui a implementação de um gerador recursivo-múltiplo-combinado de números aleatórios (combined multiple recursive random number generator), ou MRG32k3a, proposto por L'Ecuyer (para versões 2.1b9 e posteriores).

Versões anteriores utilizam o minimal standard multiplicative linear congruential generator, proposto por Park and Miller

O gerador MRG32k3a provê 1,8x1019 streams independentes de números aleatórios, cada streams sendo composto por 2,3x1015 substreams.

Cada substream possui um período de 7,6x1022

O período do gerador é de 3,1x1057

Pierre L'Ecuyer. Good parameters and implementations for combined multiple recursive random number generators. Operations Research, 1999

S.K. Park and R.W. Miller. Random number generation: Good ones are hard to find. Communications of the ACM, 1988.

Page 57: Curso de NS Rainer R. P. Couto (rainerpc@dcc.ufmg.br)rainerpc@dcc.ufmg.br

Geração de números aleatórios

Um gerador RNG default é criado no início da simulação (defaultRNG).

Se múltiplas variáveis aleatórias são utilizadas durante uma simulação, cada variável deve utilizar um objeto RNG distinto.

Quando uma nova variável RNG é criada, à sua semente é atribuído um valor de modo a gerar o próximo stream independente de números aleatórios.

A implementação permite um número máximo de 1,8x1019 var. aleatórias.

Geralmente são necessárias várias réplicas de um mesmo experimento (análise estatística)

Para cada réplica, um substream diferente deve ser utilizado para garantir que as seqüências de números aleatórios sejam independentes.

Esse processo limita o número de réplicas possíveis em, no máximo, 2,3x1015.

Pierre L'Ecuyer, Richard Simard, E. Jack Chen, and W. David Kelton. An object-oriented random number package with many long streams and substreams. Operations Research, 2001.

E também em:tools/rng.htools/rng.cc

Page 58: Curso de NS Rainer R. P. Couto (rainerpc@dcc.ufmg.br)rainerpc@dcc.ufmg.br

Semente Semente default de defaultRNG: 12345

Somente a semente de defaultRNG necessita ser inicializada Cada RNG é inicializado de modo a produzir uma seqüência

independente de números. A semente pode ser inicializada com qualquer valor entre 1 e

MAXINT (2147483647).

Para obter comportamento não-determinístico, basta inicializar a semente para 0.

A nova semente é baseada na hora corrente e em um contador.

Não deve ser usado para produzir uma seqüência independente de dados, já que não há garantia que as seqüências não irão se sobrepor.

A única forma de garantir que duas seqüências não irão se sobrepor é utilizar substreams.

Page 59: Curso de NS Rainer R. P. Couto (rainerpc@dcc.ufmg.br)rainerpc@dcc.ufmg.br

Exemplo 1 - script# Usage: ns rng-test.tcl [replication number]

if {$argc > 1} {

puts "Usage: ns rng-test.tcl \[replication number\]"

exit

}

set run 1

if { $argc == 1 } { set run [lindex $argv 0] }

if { $run < 1 } { set run 1 }

$sizeRNG next-substream

}

# seed the default RNG

global defaultRNG

$defaultRNG seed 9999

# create the RNGs and set them to the correct substream

set arrivalRNG [new RNG]

set sizeRNG [new RNG]

for {set j 1} {$j < $run} {incr j} {

$arrivalRNG next-substream

# arrival_ is a exponential random variable describing the time

# between consecutive packet arrivals

set arrival_ [new RandomVariable/Exponential]

$arrival_ set avg_ 5

$arrival_ use-rng $arrivalRNG # size_ is a uniform random variable describing packet sizes

set size_ [new RandomVariable/Uniform]

$size_ set min_ 100

$size_ set max_ 5000

$size_ use-rng $sizeRNG # print the first 5 arrival times and sizes

for {set j 0} {$j < 5} {incr j} {

puts [ format "%-8.3f %-4d" [ $arrival_ value ] \

[expr round([$size_ value])]]

}

Page 60: Curso de NS Rainer R. P. Couto (rainerpc@dcc.ufmg.br)rainerpc@dcc.ufmg.br

Exemplo 1 - script# Usage: ns rng-test.tcl [replication number]

if {$argc > 1} {

puts "Usage: ns rng-test.tcl \[replication number\]"

exit

}

set run 1

if { $argc == 1 } { set run [lindex $argv 0] }

if { $run < 1 } { set run 1 } # seed the default RNG

global defaultRNG

$defaultRNG seed 9999

$sizeRNG next-substream

}

# create the RNGs and set them to the correct substream

set arrivalRNG [new RNG]

set sizeRNG [new RNG]

for {set j 1} {$j < $run} {incr j} {

$arrivalRNG next-substream

# arrival_ is a exponential random variable describing the time

# between consecutive packet arrivals

set arrival_ [new RandomVariable/Exponential]

$arrival_ set avg_ 5

$arrival_ use-rng $arrivalRNG # size_ is a uniform random variable describing packet sizes

set size_ [new RandomVariable/Uniform]

$size_ set min_ 100

$size_ set max_ 5000

$size_ use-rng $sizeRNG # print the first 5 arrival times and sizes

for {set j 0} {$j < 5} {incr j} {

puts [ format "%-8.3f %-4d" [ $arrival_ value ] \

[expr round([$size_ value])]]

}

Page 61: Curso de NS Rainer R. P. Couto (rainerpc@dcc.ufmg.br)rainerpc@dcc.ufmg.br

Exemplo - saída

% ns rng-test.tcl 1

6.358 4783 5.828 1732 1.469 2188 0.732 3076 4.002 626

% ns rng-test.tcl 5

0.691 1187 0.204 4924 8.849 857 2.111 4505 3.200 1143

Page 62: Curso de NS Rainer R. P. Couto (rainerpc@dcc.ufmg.br)rainerpc@dcc.ufmg.br

Comandos OTcl Os seguintes comandos do RNG podem ser acessados

através do OTcl e se encontram implementados em tools/rng.cc:

seed <raiz>: atribui o parâmetro à raiz do gerador. O valor 0 indica uma raiz baseada na hora corrente e em um contador

next-random: retorna próximo número aleatório seed: retorna o valor da raiz next-substream: avança para o próximo reset-start-substream: reinicia o substream para o início da

seqüência de números aleatórios normal <avg> <stddev>: retorna um número aleatório de

uma distribuição normal segundo os parâmetros de entrada lognormal <avg> <stddev>: retorna um número aleatório

de uma distribuição lognormal segundo os parâmetros de entrada.

Page 63: Curso de NS Rainer R. P. Couto (rainerpc@dcc.ufmg.br)rainerpc@dcc.ufmg.br

Comandos OTcl

Os seguintes comandos do RNG podem ser acessados através do OTcl e se encontram implementados em tcl/lib/ns-random.tcl:

exponential <mean>: retorna um número aleatório retirado de uma distribuição exponencial segundo o parâmetro de entrada

uniform <a> <b>: retorna um inteiro retirado de uma distribuição uniforme no intervalo [a , b]

integer <k>: retorna um inteiro retirado de uma distribuição uniforme no intervalo [0 , k-1]

Page 64: Curso de NS Rainer R. P. Couto (rainerpc@dcc.ufmg.br)rainerpc@dcc.ufmg.br

Exemplo 2 - script# Usage: ns rng-test2.tcl [replication number]

if { $argc > 1 } {

puts "Usage: ns rng-test2.tcl \[replication number\]"

exit

}

set run 1

if { $argc == 1 } { set run [lindex $argv 0] }

if { $run < 1 } { set run 1 } # the default RNG is seeded with 12345

# create the RNGs and set them to the correct substream

set arrivalRNG [new RNG]

set sizeRNG [new RNG]

for { set j 1 } { $j < $run } { incr j } {

$arrivalRNG next-substream

$sizeRNG next-substream

}

# print the first 5 arrival times and sizes

for { set j 0 } { $j < 5 } { incr j } {

puts [format "%-8.3f %-4d" [$arrivalRNG lognormal 5 0.1] \

[expr round([$sizeRNG normal 5000 100])]] }

Saída % ns rng-test2.tcl 1142.776 5038 174.365 5024 147.160 4984 169.693 4981 187.972 4982

Saída % ns rng-test2.tcl 5160.993 4907 119.895 4956 149.468 5131 137.678 4985 158.936 4871

Page 65: Curso de NS Rainer R. P. Couto (rainerpc@dcc.ufmg.br)rainerpc@dcc.ufmg.br

Comandos C++ Métodos da classe RNG

O gerador de números aleatórios está implementado na classe RNGImplementation dentro de tools/rng(.h,.cc).

Note: A classe Random em tools/random.h é uma interface para a classe RNG (compatibilidade com versões anteriores)

Classe RNGImplementation: void set_seed (long seed): igual a OTcl long seed (void): retorna o valor da semente long next (void): próximo número entre [0,MAXINT] double next_double (void) próximo número entre [0,1] void reset_start_substream (void): reinicia substream void reset_next_substream (void): próximo substream

Page 66: Curso de NS Rainer R. P. Couto (rainerpc@dcc.ufmg.br)rainerpc@dcc.ufmg.br

Comandos C++ Métodos da classe RNG

Classe RNGImplementation:

int uniform (int k): retorna inteiro da dist. uniforme entre [0,k-1] double uniform (double r): dist. uniforme entre [0, r] double uniform (double a, double b): dist. uniforme entre [a,b] double exponential (void): dist. exponencial com valor médio 1.0 double exponential (double k): dist. exponencial com valor médio

k double normal (double avg, double std): dist. normal com média

e desvio padrões dados double lognormal (double avg, double std): dist. lognormal com

média e desvio padrões dados

Page 67: Curso de NS Rainer R. P. Couto (rainerpc@dcc.ufmg.br)rainerpc@dcc.ufmg.br

Exemplo - código

/* create new RNGs */ RNG arrival (23456); RNG size; Saída

161.826 506160.591 503 157.145 509 137.715 507 118.573 496

/* set the RNGs to the appropriate substream */ for (int i = 1; i < 3; i++) { arrival.reset_next_substream(); size.reset_next_substream(); }

/* print the first 5 arrival times and sizes */ for (int j = 0; j < 5; j++) { printf ("%-8.3f %-4d\n", arrival.lognormal(5, 0.1), int(size.normal(500, 10))); }

Page 68: Curso de NS Rainer R. P. Couto (rainerpc@dcc.ufmg.br)rainerpc@dcc.ufmg.br

Variáveis Aleatórias A classe RandomVariable provê uma abstração

das funcionalidades do gerador de números aleatórios e da seqüência de números gerados.

Arquivos: tools/ranvar(.h,.cc)

class RandomVariable : public TclObject { public: virtual double value() = 0; int command(int argc, const char*const* argv); RandomVariable(); protected: RNG* rng_; };

Classes que derivam dessa classe abstrata

implementam uma distribuição específica.

Cada distribuição é parametrizada com os respectivos valores. O método virtual value é

utilizado para retornar um número que segue a

distribuição implementada.

Page 69: Curso de NS Rainer R. P. Couto (rainerpc@dcc.ufmg.br)rainerpc@dcc.ufmg.br

Variáveis Aleatórias

As distribuições implementadas na versão atual e seus parâmetros são:

UniformRandomVariable: min_, max_ ExponentialRandomVariable: avg_ ParetoRandomVariable: avg_, shape_ ParetoIIRandomVariable: avg_, shape_ ConstantRandomVariable: val_ HyperExponentialRandomVariable: avg_, cov_ NormalRandomVariable: avg_, std_ LogNormalRandomVariable: avg_, std_

Page 70: Curso de NS Rainer R. P. Couto (rainerpc@dcc.ufmg.br)rainerpc@dcc.ufmg.br

Variáveis Aleatórias

A classe RandomVariable está disponível em OTcl.

Exemplo: criar uma variável randômica que gera números aleatórios uniformemente distribuídos no intervalor [10, 20] set u [new set u [new

RandomVariable/Uniform]RandomVariable/Uniform]

$u set min_ 10 $u set min_ 10

$u set max_ 20 $u set max_ 20

$u value$u value Por default, um objeto RandomVariable utiliza

o RNG default do NS. Para associar um novo RNG à variável deve-se utilizar o método use-rng.

set rng [new RNG]set rng [new RNG]

$rng seed 0 $rng seed 0

set e [newset e [new

RandomVariable/Exponential] RandomVariable/Exponential]

$e use-rng $rng$e use-rng $rng

Page 71: Curso de NS Rainer R. P. Couto (rainerpc@dcc.ufmg.br)rainerpc@dcc.ufmg.br

Integrais

Ns possui uma classe para cálculos de integrais nos arquivos tools/integrator(.h,.cc)

Aproximação da integral contínua através de somas discretas

class Integrator : public TclObject { public: Integrator(); void set(double x, double y); void newPoint(double x, double y); int command(int argc, const char*const* argv);protected: double lastx_; double lasty_; double sum_; };