\documentclass[a4paper,11pt]{article} % codificação \usepackage[utf8]{inputenc} \usepackage[T1]{fontenc} % layout \usepackage[top=2.5cm, bottom=2.5cm, left=2.5cm, right=2.5cm]{geometry} \usepackage{parskip} % Espaçamento entre parágrafos sem indentação \usepackage{titlesec} % Personalização de títulos % cor/estilo \usepackage{xcolor} \definecolor{navyblue}{RGB}{0, 40, 85} \definecolor{codegray}{rgb}{0.95,0.95,0.95} \definecolor{accent}{RGB}{0, 100, 180} \usepackage{hyperref} \hypersetup{ pdftitle={Relatório de Correção de Regressão de Desempenho em Linux}, pdfauthor={Leandro Afonso}, pdfsubject={Análise Técnica}, pdfkeywords={Linux, Java, Latency, Syscall, Optimization}, pdfcreator={pdfLaTeX} } % data \renewcommand{\today}{% \number\day\ de % \ifcase\month\or Janeiro\or Fevereiro\or Março\or Abril\or Maio\or Junho\or Julho\or Agosto\or Setembro\or Outubro\or Novembro\or Dezembro% \fi \ de \number\year% } % tabelas \usepackage{booktabs} \usepackage{array} % conf \usepackage{listings} \lstset{ backgroundcolor=\color{codegray}, basicstyle=\ttfamily\small, breakatwhitespace=false, breaklines=true, captionpos=b, commentstyle=\color{green!50!black}, keywordstyle=\color{blue}, stringstyle=\color{red}, frame=single, rulecolor=\color{black!20}, numbers=left, numberstyle=\tiny\color{gray}, stepnumber=1, tabsize=4, showstringspaces=false extendedchars=true, literate={á}{{\'a}}1 {ã}{{\~a}}1 {é}{{\'e}}1 {ç}{{\c{c}}}1 {í}{{\'i}}1 {ó}{{\'o}}1 {õ}{{\~o}}1 {ú}{{\'u}}1 {µ}{{\ensuremath{\mu}}}1 {€}{{\euro}}1, } % seccões \titleformat{\section} {\color{navyblue}\normalfont\Large\bfseries} {\thesection}{1em}{} \titleformat{\subsection} {\color{navyblue}\normalfont\large\bfseries} {\thesubsection}{1em}{} % metadados \title{\textbf{\color{navyblue}Relatório de Correção de Regressão de Desempenho em Linux}} \author{Leandro Afonso} \date{\today} \begin{document} \maketitle \section{Resumo do Problema} A simulação distribuída de tráfego demonstrou uma regressão significativa de desempenho em ambiente Linux nativo quando comparada com a execução em Windows/Wine. A tabela abaixo ilustra a discrepância nas taxas de conclusão de veículos dentro da janela de simulação fixa: \begin{table}[h] \centering \begin{tabular}{@{}lc@{}} \toprule \textbf{Ambiente} & \textbf{Taxa de Conclusão} \\ \midrule Windows / Wine & $\sim 95-100\%$ \\ Linux (OpenJDK Nativo) & $\sim 44\%$ \\ Linux (com \texttt{strace}) & $\sim 91\%$ \\ \bottomrule \end{tabular} \caption{Comparação de desempenho por ambiente.} \end{table} O \textit{insight} crucial surgiu ao descobrir que a execução sob \texttt{strace} recuperava a taxa de conclusão para 91\%. O \texttt{strace} introduz \textit{overhead} em cada \textit{syscall}, o que, paradoxalmente, estabilizou o sistema ao forçar um abrandamento natural (\textit{throttling}). \section{Causa Raiz} \textbf{O Linux executa demasiado rápido.} O Coordenador gera veículos a uma velocidade superior à capacidade de processamento das interseções distribuídas e da pilha de rede. Em Windows/Wine, o \textit{overhead} inerente à emulação e ao agendador do SO limita naturalmente a taxa de transferência do sistema. Em Linux nativo, a execução mais célere provoca uma condição de corrida sistémica: \begin{itemize} \item A geração de veículos excede a capacidade de processamento imediato dos nós. \item As filas de eventos congestionam (\textit{back up}) rapidamente nas interseções. \item Veículos gerados tardiamente não dispõem de tempo de CPU suficiente para concluir o percurso antes do fim da simulação. \end{itemize} \section{Solução Implementada} A correção consistiu na introdução de micro-atrasos (\textit{micro-throttles}) utilizando \texttt{LockSupport.parkNanos()}. Esta abordagem simula o \textit{overhead} natural presente no ambiente Windows, permitindo o escoamento das filas de E/S. \subsection{Alterações no Código} \textbf{1. Ficheiro: \texttt{SocketConnection.java}} \\ Adicionado um atraso de 50$\mu$s após operações de E/S para permitir o processamento da pilha TCP. \begin{lstlisting}[language=Java, title={SocketConnection.java (Excerto)}] // Em sendMessage() após o flush: dataOut.flush(); LockSupport.parkNanos(50000); // 50 us delay // Em receiveMessage() após readFully: dataIn.readFully(data); LockSupport.parkNanos(50000); // 50 us delay \end{lstlisting} \textbf{2. Ficheiro: \texttt{CoordinatorProcess.java}} \\ Adicionado um atraso de 100$\mu$s na geração de veículos para limitar a taxa de produção. \begin{lstlisting}[language=Java, title={CoordinatorProcess.java (Excerto)}] // Em generateAndSendVehicle(): sendVehicleToIntersection(vehicle, entryIntersection); LockSupport.parkNanos(100000); // 100 us delay \end{lstlisting} \textbf{Nota: \textnormal{Em ambos os ficheiros deve ser importado java.util.concurrent.locks.LockSupport.}} \section{Resultados e Validação} A aplicação dos atrasos sintéticos restaurou a paridade de desempenho entre os sistemas operativos. \begin{table}[h] \centering \begin{tabular}{@{}lcc@{}} \toprule \textbf{Ambiente} & \textbf{Antes da Correção} & \textbf{Após Correção} \\ \midrule Linux Nativo & $\sim 44\%$ & $\mathbf{\sim 92\%}$ \\ \bottomrule \end{tabular} \end{table} \subsection{Por que funciona?} \begin{itemize} \item \textbf{Precisão:} \texttt{LockSupport.parkNanos()} oferece um atraso preciso e não bloqueante, com impacto mínimo no agendador do SO, ao contrário de \texttt{Thread.sleep()}. \item \textbf{Ritmo de E/S (50$\mu$s):} Abranda a comunicação via \textit{socket} o suficiente para evitar a saturação dos \textit{buffers} de receção das interseções. \item \textbf{Controlo de Fluxo (100$\mu$s):} Limita a produção do Coordenador, garantindo que o sistema a jusante consegue processar os eventos em tempo útil. \end{itemize} \subsection{Verificação} Para validar a correção no ambiente de desenvolvimento: \begin{lstlisting}[language=bash] mvn clean compile mvn javafx:run \end{lstlisting} \textbf{Resultado Esperado:} Taxa de conclusão superior a 90\%. \section{Abordagens Alternativas (Falhadas)} As seguintes tentativas foram realizadas antes da solução final, sem sucesso: \begin{itemize} \item \textbf{Thread.sleep(1):} Demasiado impreciso (granularidade mínima de $\sim$1ms em Linux), causando atrasos excessivos. \item \textbf{Thread.yield():} Sem efeito prático no agendador CFS do Linux neste contexto. \item \textbf{Garbage Collectors:} A alteração entre G1, Parallel e Shenandoah não surtiu efeito. \item \textbf{Versão Java:} Testes com Java 17 e 25 mostraram o mesmo comportamento. \item \textbf{Prioridade de Threads:} Ajustes de prioridade na JVM foram ignorados pelo SO. \end{itemize} \end{document}