This commit is contained in:
Martin Slachta
2026-07-28 22:28:02 +02:00
parent c0c1540740
commit 3278c5762c
9 changed files with 426 additions and 397 deletions
+88 -88
View File
@@ -108,114 +108,114 @@
\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.2.1}Klient Replikátoru}{29}{subsubsection.4.2.1}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.2.2}Interpolace}{29}{subsubsection.4.2.2}\protected@file@percent }
\BKM@entry{id=41,open,dest={73756273756273656374696F6E2E342E322E33},srcline={742}}{5C3337365C3337375C303030345C3030302E5C303030325C3030302E5C303030335C3030305C3034305C303030525C3030306F5C3030306C5C3030306C5C303030625C303030615C303030635C3030306B}
\BKM@entry{id=42,open,dest={73756273656374696F6E2E342E33},srcline={751}}{5C3337365C3337375C303030345C3030302E5C303030335C3030305C3034305C303030505C3030306F5C303030735C3030305C3335355C3030306C5C3030305C3334315C3030306E5C3030305C3335355C3030305C3034305C3030307A5C303030705C303030725C3030305C3334315C30303076}
\BKM@entry{id=43,open,dest={73756273756273656374696F6E2E342E332E31},srcline={760}}{5C3337365C3337375C303030345C3030302E5C303030335C3030302E5C303030315C3030305C3034305C3030304B5C3030305C3336335C303030645C3030306F5C303030765C3030305C3334315C3030306E5C3030305C3335355C3030305C3034305C3030307A5C303030705C303030725C3030305C3334315C30303076}
\BKM@entry{id=44,open,dest={73756273756273656374696F6E2E342E332E32},srcline={768}}{5C3337365C3337375C303030345C3030302E5C303030335C3030302E5C303030325C3030305C3034305C303030495C3030306D5C303030705C3030306C5C303030655C3030306D5C303030655C3030306E5C303030745C303030615C303030635C30303065}
\BKM@entry{id=42,open,dest={73756273656374696F6E2E342E33},srcline={752}}{5C3337365C3337375C303030345C3030302E5C303030335C3030305C3034305C303030505C3030306F5C303030735C3030305C3335355C3030306C5C3030305C3334315C3030306E5C3030305C3335355C3030305C3034305C3030307A5C303030705C303030725C3030305C3334315C30303076}
\BKM@entry{id=43,open,dest={73756273756273656374696F6E2E342E332E31},srcline={765}}{5C3337365C3337375C303030345C3030302E5C303030335C3030302E5C303030315C3030305C3034305C3030304B5C3030305C3336335C303030645C3030306F5C303030765C3030305C3334315C3030306E5C3030305C3335355C3030305C3034305C3030307A5C303030705C303030725C3030305C3334315C30303076}
\BKM@entry{id=44,open,dest={73756273756273656374696F6E2E342E332E32},srcline={773}}{5C3337365C3337375C303030345C3030302E5C303030335C3030302E5C303030325C3030305C3034305C303030495C3030306D5C303030705C3030306C5C303030655C3030306D5C303030655C3030306E5C303030745C303030615C303030635C30303065}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.2.3}Rollback}{30}{subsubsection.4.2.3}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {4.3}Posílání zpráv}{30}{subsection.4.3}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.3.1}Kódování zpráv}{30}{subsubsection.4.3.1}\protected@file@percent }
\BKM@entry{id=45,open,dest={73756273756273656374696F6E2E342E332E33},srcline={772}}{5C3337365C3337375C303030345C3030302E5C303030335C3030302E5C303030335C3030305C3034305C303030445C303030655C303030745C303030655C3030306B5C303030635C303030655C3030305C3034305C303030615C3030305C3034305C3030306E5C3030305C3334315C303030705C303030725C303030615C303030765C303030615C3030305C3034305C303030635C303030685C303030795C30303062}
\BKM@entry{id=46,open,dest={73756273656374696F6E2E342E34},srcline={779}}{5C3337365C3337375C303030345C3030302E5C303030345C3030305C3034305C303030535C303030655C303030725C303030695C303030615C3030306C5C303030695C3030307A5C303030615C303030635C30303065}
\BKM@entry{id=45,open,dest={73756273756273656374696F6E2E342E332E33},srcline={777}}{5C3337365C3337375C303030345C3030302E5C303030335C3030302E5C303030335C3030305C3034305C303030445C303030655C303030745C303030655C3030306B5C303030635C303030655C3030305C3034305C303030615C3030305C3034305C3030306E5C3030305C3334315C303030705C303030725C303030615C303030765C303030615C3030305C3034305C303030635C303030685C303030795C30303062}
\BKM@entry{id=46,open,dest={73756273656374696F6E2E342E34},srcline={784}}{5C3337365C3337375C303030345C3030302E5C303030345C3030305C3034305C303030535C303030655C303030725C303030695C303030615C3030306C5C303030695C3030307A5C303030615C303030635C30303065}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.3.2}Implementace}{31}{subsubsection.4.3.2}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.3.3}Detekce a náprava chyb}{31}{subsubsection.4.3.3}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {4.4}Serializace}{31}{subsection.4.4}\protected@file@percent }
\BKM@entry{id=47,open,dest={73756273656374696F6E2E342E35},srcline={807}}{5C3337365C3337375C303030345C3030302E5C303030355C3030305C3034305C3030304D5C303030655C303030745C303030725C303030695C3030306B5C30303079}
\BKM@entry{id=48,open,dest={73756273756273656374696F6E2E342E352E31},srcline={811}}{5C3337365C3337375C303030345C3030302E5C303030355C3030302E5C303030315C3030305C3034305C303030505C3030306F5C303030735C303030745C303030675C303030725C303030655C303030535C303030515C3030304C}
\BKM@entry{id=47,open,dest={73756273656374696F6E2E342E35},srcline={816}}{5C3337365C3337375C303030345C3030302E5C303030355C3030305C3034305C303030505C303030725C3030306F5C303030745C3030306F5C3030306B5C3030306F5C3030306C5C3030305C3034305C303030515C303030555C303030495C303030435C30303072}
\@writefile{lol}{\contentsline {lstlisting}{\numberline {2}cpp}{32}{lstlisting.2}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {4.5}Metriky}{32}{subsection.4.5}\protected@file@percent }
\BKM@entry{id=49,open,dest={73756273756273656374696F6E2E342E352E32},srcline={815}}{5C3337365C3337375C303030345C3030302E5C303030355C3030302E5C303030325C3030305C3034305C303030545C303030695C3030306D5C303030655C303030735C303030635C303030615C3030306C5C303030655C303030445C30303042}
\BKM@entry{id=50,open,dest={73756273756273656374696F6E2E342E352E33},srcline={819}}{5C3337365C3337375C303030345C3030302E5C303030355C3030302E5C303030335C3030305C3034305C303030475C303030725C303030615C303030665C303030615C3030306E5C30303061}
\BKM@entry{id=51,open,dest={73756273756273656374696F6E2E342E352E34},srcline={831}}{5C3337365C3337375C303030345C3030302E5C303030355C3030302E5C303030345C3030305C3034305C3030304F5C303030725C303030635C303030685C303030655C303030735C303030745C303030725C303030615C303030635C30303065}
\@writefile{lof}{\contentsline {figure}{\numberline {6}{\ignorespaces Příklad Grafana dashboardu}}{33}{figure.6}\protected@file@percent }
\newlabel{fig:grafana}{{6}{33}{Příklad Grafana dashboardu}{figure.6}{}}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.5.1}PostgreSQL}{33}{subsubsection.4.5.1}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.5.2}TimescaleDB}{33}{subsubsection.4.5.2}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.5.3}Grafana}{33}{subsubsection.4.5.3}\protected@file@percent }
\BKM@entry{id=52,open,dest={73756273756273656374696F6E2E342E352E35},srcline={837}}{5C3337365C3337375C303030345C3030302E5C303030355C3030302E5C303030355C3030305C3034305C303030495C3030306D5C303030475C303030755C30303069}
\BKM@entry{id=53,open,dest={73756273756273656374696F6E2E342E352E36},srcline={843}}{5C3337365C3337375C303030345C3030302E5C303030355C3030302E5C303030365C3030305C3034305C303030545C303030725C303030615C303030635C30303079}
\BKM@entry{id=54,open,dest={73756273756273656374696F6E2E342E352E37},srcline={857}}{5C3337365C3337375C303030345C3030302E5C303030355C3030302E5C303030375C3030305C3034305C3030304B5C3030306F5C3030306E5C3030306B5C303030725C3030305C3335315C303030745C3030306E5C3030305C3335355C3030305C3034305C3030306D5C303030655C303030745C303030725C303030695C3030306B5C30303079}
\@writefile{lof}{\contentsline {figure}{\numberline {7}{\ignorespaces Jeden snímek v Tracy}}{34}{figure.7}\protected@file@percent }
\newlabel{fig:frame_in_tracy}{{7}{34}{Jeden snímek v Tracy}{figure.7}{}}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.5.4}Orchestrace}{34}{subsubsection.4.5.4}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.5.5}ImGui}{34}{subsubsection.4.5.5}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.5.6}Tracy}{34}{subsubsection.4.5.6}\protected@file@percent }
\BKM@entry{id=55,open,dest={73756273756273656374696F6E2E342E352E38},srcline={873}}{5C3337365C3337375C303030345C3030302E5C303030355C3030302E5C303030385C3030305C3034305C303030535C303030625C3030305C3335355C303030725C3030305C3334315C3030306E5C3030305C3335355C3030305C3034305C303030765C3030305C3034305C303030725C303030655C3030305C3334315C3030306C5C3030306E5C3030305C3335315C3030306D5C3030305C3034305C3030315C3031355C303030615C303030735C30303065}
\BKM@entry{id=56,open,dest={73756273656374696F6E2E342E36},srcline={883}}{5C3337365C3337375C303030345C3030302E5C303030365C3030305C3034305C303030505C303030725C3030306F5C303030745C3030306F5C3030306B5C3030306F5C3030306C5C3030305C3034305C303030515C303030555C303030495C303030435C30303072}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.5.7}Konkrétní metriky}{35}{subsubsection.4.5.7}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.5.8}Sbírání v reálném čase}{35}{subsubsection.4.5.8}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {4.6}Protokol QUICr}{35}{subsection.4.6}\protected@file@percent }
\BKM@entry{id=57,open,dest={73756273756273656374696F6E2E342E362E31},srcline={893}}{5C3337365C3337375C303030345C3030302E5C303030365C3030302E5C303030315C3030305C3034305C303030525C3030305C3334315C3030306D5C303030655C30303063}
\BKM@entry{id=58,open,dest={73756273756273656374696F6E2E342E362E32},srcline={904}}{5C3337365C3337375C303030345C3030302E5C303030365C3030302E5C303030325C3030305C3034305C303030485C303030615C3030306E5C303030645C303030735C303030685C303030615C3030306B5C30303065}
\BKM@entry{id=59,open,dest={73756273756273656374696F6E2E342E362E33},srcline={938}}{5C3337365C3337375C303030345C3030302E5C303030365C3030302E5C303030335C3030305C3034305C303030535C303030705C3030306F5C3030306C5C303030655C303030685C3030306C5C303030695C303030765C3030306F5C303030735C30303074}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.6.1}Rámec}{36}{subsubsection.4.6.1}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.6.2}Handshake}{36}{subsubsection.4.6.2}\protected@file@percent }
\@writefile{lof}{\contentsline {figure}{\numberline {8}{\ignorespaces Stavový stroj QUICr handshake}}{37}{figure.8}\protected@file@percent }
\newlabel{fig:quicr_handshake}{{8}{37}{Stavový stroj QUICr handshake}{figure.8}{}}
\BKM@entry{id=60,open,dest={73756273756273656374696F6E2E342E362E34},srcline={960}}{5C3337365C3337375C303030345C3030302E5C303030365C3030302E5C303030345C3030305C3034305C303030455C3030306E5C3030306B5C3030306F5C303030645C3030305C3335315C30303072}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.6.3}Spolehlivost}{38}{subsubsection.4.6.3}\protected@file@percent }
\newlabel{sec:quicr_reliability}{{4.6.3}{38}{Spolehlivost}{subsubsection.4.6.3}{}}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.6.4}Enkodér}{38}{subsubsection.4.6.4}\protected@file@percent }
\BKM@entry{id=61,open,dest={73756273756273656374696F6E2E342E362E35},srcline={967}}{5C3337365C3337375C303030345C3030302E5C303030365C3030302E5C303030355C3030305C3034305C303030545C303030655C303030735C303030745C3030306F5C303030765C3030305C3334315C3030306E5C3030305C333535}
\BKM@entry{id=62,open,dest={73756273756273656374696F6E2E342E362E36},srcline={974}}{5C3337365C3337375C303030345C3030302E5C303030365C3030302E5C303030365C3030305C3034305C3030304D5C3030315C3033335C3030315C3133315C303030655C3030306E5C3030305C333535}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.6.5}Testování}{39}{subsubsection.4.6.5}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.6.6}Měření}{39}{subsubsection.4.6.6}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {3}Příklad volání TC}{39}{lstlisting.3}\protected@file@percent }
\@writefile{lof}{\contentsline {figure}{\numberline {9}{\ignorespaces Porovnání odezvy TCP a QUICr}}{40}{figure.9}\protected@file@percent }
\newlabel{fig:latencycomparison}{{9}{40}{Porovnání odezvy TCP a QUICr}{figure.9}{}}
\newlabel{fig:integrationcomparison}{{4.6.6}{40}{Měření}{figure.9}{}}
\@writefile{lof}{\contentsline {figure}{\numberline {10}{\ignorespaces Porovnání integrace TCP a QUICr}}{40}{figure.10}\protected@file@percent }
\BKM@entry{id=63,open,dest={73756273656374696F6E2E342E37},srcline={1025}}{5C3337365C3337375C303030345C3030302E5C303030375C3030305C3034305C3030304F5C303030705C303030745C303030695C3030306D5C303030615C3030306C5C303030695C3030307A5C303030615C303030635C303030655C3030305C3034305C303030725C303030655C303030705C3030306C5C303030695C3030306B5C3030305C3334315C303030745C3030306F5C303030725C30303075}
\newlabel{fig:playerbenchmark}{{4.6.6}{41}{Měření}{figure.10}{}}
\@writefile{lof}{\contentsline {figure}{\numberline {11}{\ignorespaces 301 připojených hráčů}}{41}{figure.11}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {4.7}Optimalizace replikátoru}{41}{subsection.4.7}\protected@file@percent }
\newlabel{fig:tracyreplicator}{{4.7}{42}{Optimalizace replikátoru}{subsection.4.7}{}}
\@writefile{lof}{\contentsline {figure}{\numberline {12}{\ignorespaces Analýza replikátoru}}{42}{figure.12}\protected@file@percent }
\newlabel{fig:ecs_optimization_tracy_01}{{4.7}{42}{Optimalizace replikátoru}{figure.12}{}}
\@writefile{lof}{\contentsline {figure}{\numberline {13}{\ignorespaces Analýza optimalizace replikátoru pro ECS}}{42}{figure.13}\protected@file@percent }
\BKM@entry{id=64,open,dest={73756273656374696F6E2E342E38},srcline={1078}}{5C3337365C3337375C303030345C3030302E5C303030385C3030305C3034305C3030304F5C303030705C303030745C303030695C3030306D5C303030615C3030306C5C303030695C3030307A5C303030615C303030635C303030655C3030305C3034305C3030306D5C303030615C3030306E5C303030615C3030315C3137365C303030655C303030725C303030615C3030305C3034305C3030307A5C3030305C3334315C3030306A5C3030306D5C3030315C313537}
\newlabel{fig:ecs_optimization_tracy_02}{{4.7}{43}{Optimalizace replikátoru}{figure.13}{}}
\@writefile{lof}{\contentsline {figure}{\numberline {14}{\ignorespaces Analýza optimalizace replikátoru pro ECS}}{43}{figure.14}\protected@file@percent }
\newlabel{table:serialization_comparison}{{4.7}{43}{Optimalizace replikátoru}{figure.14}{}}
\@writefile{lof}{\contentsline {figure}{\numberline {15}{\ignorespaces Porovnání serializátorů}}{43}{figure.15}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {4.8}Optimalizace manažera zájmů}{43}{subsection.4.8}\protected@file@percent }
\BKM@entry{id=65,open,dest={73756273756273656374696F6E2E342E382E31},srcline={1121}}{5C3337365C3337375C303030345C3030302E5C303030385C3030302E5C303030315C3030305C3034305C303030435C3030306F5C3030306E5C303030675C303030655C303030735C303030745C303030695C3030306F5C3030306E5C3030305C3034305C303030635C3030306F5C3030306E5C303030745C303030725C3030306F5C3030306C}
\BKM@entry{id=66,open,dest={73756273756273656374696F6E2E342E382E32},srcline={1123}}{5C3337365C3337375C303030345C3030302E5C303030385C3030302E5C303030325C3030305C3034305C303030425C303030615C3030306E5C303030645C303030775C303030695C303030645C303030745C303030685C3030305C3034305C303030635C3030306F5C3030306E5C303030745C303030725C3030306F5C3030306C}
\BKM@entry{id=67,open,dest={73756273656374696F6E2E342E39},srcline={1127}}{5C3337365C3337375C303030345C3030302E5C303030395C3030305C3034305C303030535C303030685C303030615C303030725C303030645C303030695C3030306E5C30303067}
\BKM@entry{id=68,open,dest={73756273656374696F6E2E342E3130},srcline={1131}}{5C3337365C3337375C303030345C3030302E5C303030315C303030305C3030305C3034305C303030485C3030306F5C303030725C303030695C3030307A5C3030306F5C3030306E5C303030745C3030305C3334315C3030306C5C3030306E5C3030305C3335355C3030305C3034305C3030315C3134315C3030306B5C3030305C3334315C3030306C5C3030306F5C303030765C3030305C3334315C3030306E5C3030305C333535}
\newlabel{table:range_query_comparison}{{4.8}{44}{Optimalizace manažera zájmů}{subsection.4.8}{}}
\@writefile{lof}{\contentsline {figure}{\numberline {16}{\ignorespaces Porovnání algoritmů}}{44}{figure.16}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.8.1}Congestion control}{44}{subsubsection.4.8.1}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.8.2}Bandwidth control}{44}{subsubsection.4.8.2}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {4.9}Sharding}{44}{subsection.4.9}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {4.10}Horizontální škálování}{44}{subsection.4.10}\protected@file@percent }
\BKM@entry{id=69,open,dest={73656374696F6E2E35},srcline={1151}}{5C3337365C3337375C303030355C3030305C3034305C303030565C3030305C3337355C303030735C3030306C5C303030655C303030645C3030306E5C3030305C3334315C3030305C3034305C303030685C303030725C30303061}
\BKM@entry{id=70,open,dest={73656374696F6E2E36},srcline={1157}}{5C3337365C3337375C303030365C3030305C3034305C3030304D5C3030315C3033335C3030315C3133315C3030315C3033335C3030306E5C3030305C333535}
\BKM@entry{id=71,open,dest={73756273656374696F6E2E362E31},srcline={1163}}{5C3337365C3337375C303030365C3030302E5C303030315C3030305C3034305C3030305A5C3030305C3334315C303030765C3030315C3033335C303030725C30303079}
\@writefile{toc}{\contentsline {section}{\numberline {5}Výsledná hra}{45}{section.5}\protected@file@percent }
\@writefile{toc}{\contentsline {section}{\numberline {6}Měřění}{45}{section.6}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {6.1}Závěry}{45}{subsection.6.1}\protected@file@percent }
\newlabel{fig:zone_cluster_architecture}{{4.10}{46}{Horizontální škálování}{subsection.4.10}{}}
\@writefile{lof}{\contentsline {figure}{\numberline {17}{\ignorespaces Architektura systému s zone clusterem}}{46}{figure.17}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {4.5}Protokol QUICr}{32}{subsection.4.5}\protected@file@percent }
\BKM@entry{id=48,open,dest={73756273756273656374696F6E2E342E352E31},srcline={829}}{5C3337365C3337375C303030345C3030302E5C303030355C3030302E5C303030315C3030305C3034305C303030525C3030305C3334315C3030306D5C303030635C30303065}
\BKM@entry{id=49,open,dest={73756273756273656374696F6E2E342E352E32},srcline={842}}{5C3337365C3337375C303030345C3030302E5C303030355C3030302E5C303030325C3030305C3034305C303030485C303030615C3030306E5C303030645C303030735C303030685C303030615C3030306B5C30303065}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.5.1}Rámce}{33}{subsubsection.4.5.1}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.5.2}Handshake}{33}{subsubsection.4.5.2}\protected@file@percent }
\BKM@entry{id=50,open,dest={73756273756273656374696F6E2E342E352E33},srcline={876}}{5C3337365C3337375C303030345C3030302E5C303030355C3030302E5C303030335C3030305C3034305C303030535C303030705C3030306F5C3030306C5C303030655C303030685C3030306C5C303030695C303030765C3030306F5C303030735C30303074}
\@writefile{lof}{\contentsline {figure}{\numberline {6}{\ignorespaces Stavový stroj QUICr handshake}}{34}{figure.6}\protected@file@percent }
\newlabel{fig:quicr_handshake}{{6}{34}{Stavový stroj QUICr handshake}{figure.6}{}}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.5.3}Spolehlivost}{34}{subsubsection.4.5.3}\protected@file@percent }
\newlabel{sec:quicr_reliability}{{4.5.3}{34}{Spolehlivost}{subsubsection.4.5.3}{}}
\BKM@entry{id=51,open,dest={73756273756273656374696F6E2E342E352E34},srcline={898}}{5C3337365C3337375C303030345C3030302E5C303030355C3030302E5C303030345C3030305C3034305C303030455C3030306E5C3030306B5C3030306F5C303030645C3030305C3335315C30303072}
\BKM@entry{id=52,open,dest={73756273756273656374696F6E2E342E352E35},srcline={906}}{5C3337365C3337375C303030345C3030302E5C303030355C3030302E5C303030355C3030305C3034305C303030545C303030655C303030735C303030745C3030306F5C303030765C3030305C3334315C3030306E5C3030305C333535}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.5.4}Enkodér}{35}{subsubsection.4.5.4}\protected@file@percent }
\BKM@entry{id=53,open,dest={73756273756273656374696F6E2E342E352E36},srcline={937}}{5C3337365C3337375C303030345C3030302E5C303030355C3030302E5C303030365C3030305C3034305C303030435C3030306F5C3030306E5C303030675C303030655C303030735C303030745C303030695C3030306F5C3030306E5C3030305C3034305C303030635C3030306F5C3030306E5C303030745C303030725C3030306F5C3030306C}
\BKM@entry{id=54,open,dest={73756273756273656374696F6E2E342E352E37},srcline={939}}{5C3337365C3337375C303030345C3030302E5C303030355C3030302E5C303030375C3030305C3034305C303030425C303030615C3030306E5C303030645C303030775C303030695C303030645C303030745C303030685C3030305C3034305C303030635C3030306F5C3030306E5C303030745C303030725C3030306F5C3030306C}
\BKM@entry{id=55,open,dest={73756273656374696F6E2E342E36},srcline={943}}{5C3337365C3337375C303030345C3030302E5C303030365C3030305C3034305C303030535C303030685C303030615C303030725C303030645C303030695C3030306E5C30303067}
\BKM@entry{id=56,open,dest={73756273656374696F6E2E342E37},srcline={947}}{5C3337365C3337375C303030345C3030302E5C303030375C3030305C3034305C303030485C3030306F5C303030725C303030695C3030307A5C3030306F5C3030306E5C303030745C3030305C3334315C3030306C5C3030306E5C3030305C3335355C3030305C3034305C3030315C3134315C3030306B5C3030305C3334315C3030306C5C3030306F5C303030765C3030305C3334315C3030306E5C3030305C333535}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.5.5}Testování}{36}{subsubsection.4.5.5}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.5.6}Congestion control}{36}{subsubsection.4.5.6}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.5.7}Bandwidth control}{36}{subsubsection.4.5.7}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {4.6}Sharding}{36}{subsection.4.6}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {4.7}Horizontální škálování}{36}{subsection.4.7}\protected@file@percent }
\BKM@entry{id=57,open,dest={73656374696F6E2E35},srcline={967}}{5C3337365C3337375C303030355C3030305C3034305C303030565C3030305C3337355C303030735C3030306C5C303030655C303030645C3030306E5C3030305C3334315C3030305C3034305C303030685C303030725C30303061}
\BKM@entry{id=58,open,dest={73656374696F6E2E36},srcline={973}}{5C3337365C3337375C303030365C3030305C3034305C3030304D5C3030315C3033335C3030315C3133315C3030315C3033335C3030306E5C3030305C333535}
\BKM@entry{id=59,open,dest={73756273656374696F6E2E362E31},srcline={976}}{5C3337365C3337375C303030365C3030302E5C303030315C3030305C3034305C3030304D5C303030655C303030745C303030725C303030695C3030306B5C30303079}
\newlabel{fig:zone_cluster_architecture}{{4.7}{37}{Horizontální škálování}{subsection.4.7}{}}
\@writefile{lof}{\contentsline {figure}{\numberline {7}{\ignorespaces Architektura systému s zone clusterem}}{37}{figure.7}\protected@file@percent }
\@writefile{toc}{\contentsline {section}{\numberline {5}Výsledná hra}{37}{section.5}\protected@file@percent }
\BKM@entry{id=60,open,dest={73756273756273656374696F6E2E362E312E31},srcline={980}}{5C3337365C3337375C303030365C3030302E5C303030315C3030302E5C303030315C3030305C3034305C303030505C3030306F5C303030735C303030745C303030675C303030725C303030655C303030535C303030515C3030304C}
\BKM@entry{id=61,open,dest={73756273756273656374696F6E2E362E312E32},srcline={984}}{5C3337365C3337375C303030365C3030302E5C303030315C3030302E5C303030325C3030305C3034305C303030545C303030695C3030306D5C303030655C303030735C303030635C303030615C3030306C5C303030655C303030445C30303042}
\BKM@entry{id=62,open,dest={73756273756273656374696F6E2E362E312E33},srcline={988}}{5C3337365C3337375C303030365C3030302E5C303030315C3030302E5C303030335C3030305C3034305C303030475C303030725C303030615C303030665C303030615C3030306E5C30303061}
\BKM@entry{id=63,open,dest={73756273756273656374696F6E2E362E312E34},srcline={1000}}{5C3337365C3337375C303030365C3030302E5C303030315C3030302E5C303030345C3030305C3034305C3030304F5C303030725C303030635C303030685C303030655C303030735C303030745C303030725C303030615C303030635C30303065}
\@writefile{toc}{\contentsline {section}{\numberline {6}Měřění}{38}{section.6}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {6.1}Metriky}{38}{subsection.6.1}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {6.1.1}PostgreSQL}{38}{subsubsection.6.1.1}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {6.1.2}TimescaleDB}{38}{subsubsection.6.1.2}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {6.1.3}Grafana}{38}{subsubsection.6.1.3}\protected@file@percent }
\BKM@entry{id=64,open,dest={73756273756273656374696F6E2E362E312E35},srcline={1006}}{5C3337365C3337375C303030365C3030302E5C303030315C3030302E5C303030355C3030305C3034305C303030495C3030306D5C303030475C303030755C30303069}
\BKM@entry{id=65,open,dest={73756273756273656374696F6E2E362E312E36},srcline={1012}}{5C3337365C3337375C303030365C3030302E5C303030315C3030302E5C303030365C3030305C3034305C303030545C303030725C303030615C303030635C30303079}
\@writefile{lof}{\contentsline {figure}{\numberline {8}{\ignorespaces Příklad Grafana dashboardu}}{39}{figure.8}\protected@file@percent }
\newlabel{fig:grafana}{{8}{39}{Příklad Grafana dashboardu}{figure.8}{}}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {6.1.4}Orchestrace}{39}{subsubsection.6.1.4}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {6.1.5}ImGui}{39}{subsubsection.6.1.5}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {6.1.6}Tracy}{39}{subsubsection.6.1.6}\protected@file@percent }
\BKM@entry{id=66,open,dest={73756273756273656374696F6E2E362E312E37},srcline={1028}}{5C3337365C3337375C303030365C3030302E5C303030315C3030302E5C303030375C3030305C3034305C3030304B5C3030306F5C3030306E5C3030306B5C303030725C3030305C3335315C303030745C3030306E5C3030305C3335355C3030305C3034305C3030306D5C303030655C303030745C303030725C303030695C3030306B5C30303079}
\BKM@entry{id=67,open,dest={73756273756273656374696F6E2E362E312E38},srcline={1044}}{5C3337365C3337375C303030365C3030302E5C303030315C3030302E5C303030385C3030305C3034305C303030535C303030625C3030305C3335355C303030725C3030305C3334315C3030306E5C3030305C3335355C3030305C3034305C303030765C3030305C3034305C303030725C303030655C3030305C3334315C3030306C5C3030306E5C3030305C3335315C3030306D5C3030305C3034305C3030315C3031355C303030615C303030735C30303065}
\BKM@entry{id=68,open,dest={73756273656374696F6E2E362E32},srcline={1049}}{5C3337365C3337375C303030365C3030302E5C303030325C3030305C3034305C303030515C303030555C303030495C303030435C30303072}
\@writefile{lof}{\contentsline {figure}{\numberline {9}{\ignorespaces Jeden snímek v Tracy}}{40}{figure.9}\protected@file@percent }
\newlabel{fig:frame_in_tracy}{{9}{40}{Jeden snímek v Tracy}{figure.9}{}}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {6.1.7}Konkrétní metriky}{40}{subsubsection.6.1.7}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {6.1.8}Sbírání v reálném čase}{40}{subsubsection.6.1.8}\protected@file@percent }
\BKM@entry{id=69,open,dest={73756273656374696F6E2E362E33},srcline={1094}}{5C3337365C3337375C303030365C3030302E5C303030335C3030305C3034305C3030304F5C303030705C303030745C303030695C3030306D5C303030615C3030306C5C303030695C3030307A5C303030615C303030635C303030655C3030305C3034305C303030725C303030655C303030705C3030306C5C303030695C3030306B5C3030305C3334315C303030745C3030306F5C303030725C30303075}
\@writefile{toc}{\contentsline {subsection}{\numberline {6.2}QUICr}{41}{subsection.6.2}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {3}Příklad volání TC}{41}{lstlisting.3}\protected@file@percent }
\@writefile{lof}{\contentsline {figure}{\numberline {10}{\ignorespaces Porovnání odezvy TCP a QUICr}}{42}{figure.10}\protected@file@percent }
\newlabel{fig:latencycomparison}{{10}{42}{Porovnání odezvy TCP a QUICr}{figure.10}{}}
\newlabel{fig:integrationcomparison}{{6.2}{42}{QUICr}{figure.10}{}}
\@writefile{lof}{\contentsline {figure}{\numberline {11}{\ignorespaces Porovnání integrace TCP a QUICr}}{42}{figure.11}\protected@file@percent }
\newlabel{fig:playerbenchmark}{{6.2}{43}{QUICr}{figure.11}{}}
\@writefile{lof}{\contentsline {figure}{\numberline {12}{\ignorespaces 301 připojených hráčů}}{43}{figure.12}\protected@file@percent }
\newlabel{fig:tracyreplicator}{{6.3}{43}{Optimalizace replikátoru}{subsection.6.3}{}}
\@writefile{lof}{\contentsline {figure}{\numberline {13}{\ignorespaces Analýza replikátoru}}{43}{figure.13}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {6.3}Optimalizace replikátoru}{43}{subsection.6.3}\protected@file@percent }
\newlabel{fig:ecs_optimization_tracy_01}{{6.3}{44}{Optimalizace replikátoru}{figure.13}{}}
\@writefile{lof}{\contentsline {figure}{\numberline {14}{\ignorespaces Analýza optimalizace replikátoru pro ECS}}{44}{figure.14}\protected@file@percent }
\newlabel{fig:ecs_optimization_tracy_02}{{6.3}{44}{Optimalizace replikátoru}{figure.14}{}}
\@writefile{lof}{\contentsline {figure}{\numberline {15}{\ignorespaces Analýza optimalizace replikátoru pro ECS}}{44}{figure.15}\protected@file@percent }
\BKM@entry{id=70,open,dest={73756273656374696F6E2E362E34},srcline={1147}}{5C3337365C3337375C303030365C3030302E5C303030345C3030305C3034305C3030304F5C303030705C303030745C303030695C3030306D5C303030615C3030306C5C303030695C3030307A5C303030615C303030635C303030655C3030305C3034305C3030306D5C303030615C3030306E5C303030615C3030315C3137365C303030655C303030725C303030615C3030305C3034305C3030307A5C3030305C3334315C3030306A5C3030306D5C3030315C313537}
\BKM@entry{id=71,open,dest={73756273656374696F6E2E362E35},srcline={1177}}{5C3337365C3337375C303030365C3030302E5C303030355C3030305C3034305C3030305A5C3030305C3334315C303030765C3030315C3033335C303030725C30303079}
\newlabel{table:serialization_comparison}{{6.3}{45}{Optimalizace replikátoru}{figure.15}{}}
\@writefile{lof}{\contentsline {figure}{\numberline {16}{\ignorespaces Porovnání serializátorů}}{45}{figure.16}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {6.4}Optimalizace manažera zájmů}{45}{subsection.6.4}\protected@file@percent }
\newlabel{table:range_query_comparison}{{6.4}{46}{Optimalizace manažera zájmů}{subsection.6.4}{}}
\@writefile{lof}{\contentsline {figure}{\numberline {17}{\ignorespaces Porovnání algoritmů}}{46}{figure.17}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {6.5}Závěry}{46}{subsection.6.5}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {4}Sazba závěrů}{46}{lstlisting.4}\protected@file@percent }
\BKM@entry{id=72,open,dest={73656374696F6E2A2E33},srcline={1184}}{5C3337365C3337375C3030305A5C3030305C3334315C303030765C3030315C3033335C30303072}
\BKM@entry{id=72,open,dest={73656374696F6E2A2E33},srcline={1198}}{5C3337365C3337375C3030305A5C3030305C3334315C303030765C3030315C3033335C30303072}
\@writefile{toc}{\contentsline {section}{Z\'av\v er}{47}{section*.3}\protected@file@percent }
\babel@aux{czech}{}
\babel@aux{czech}{}
\BKM@entry{id=73,open,dest={73656374696F6E2A2E35},srcline={1187}}{5C3337365C3337375C303030435C3030306F5C3030306E5C303030635C3030306C5C303030755C303030735C303030695C3030306F5C3030306E5C30303073}
\BKM@entry{id=73,open,dest={73656374696F6E2A2E35},srcline={1201}}{5C3337365C3337375C303030435C3030306F5C3030306E5C303030635C3030306C5C303030755C303030735C303030695C3030306F5C3030306E5C30303073}
\@writefile{toc}{\contentsline {section}{Conclusions}{48}{section*.5}\protected@file@percent }
\babel@aux{english}{}
\babel@aux{czech}{}
\BKM@entry{id=74,open,dest={617070656E6469782E41},srcline={1194}}{5C3337365C3337375C303030415C3030305C3034305C303030505C303030725C303030765C3030306E5C3030305C3335355C3030305C3034305C303030705C3030315C3133315C3030305C3335355C3030306C5C3030306F5C303030685C30303061}
\BKM@entry{id=75,open,dest={617070656E6469782E42},srcline={1197}}{5C3337365C3337375C303030425C3030305C3034305C303030445C303030725C303030755C303030685C3030305C3334315C3030305C3034305C303030705C3030315C3133315C3030305C3335355C3030306C5C3030306F5C303030685C30303061}
\BKM@entry{id=76,open,dest={617070656E6469782E43},srcline={1202}}{5C3337365C3337375C303030435C3030305C3034305C3030304F5C303030625C303030735C303030615C303030685C3030305C3034305C303030655C3030306C5C303030655C3030306B5C303030745C303030725C3030306F5C3030306E5C303030695C303030635C3030306B5C3030305C3337355C303030635C303030685C3030305C3034305C303030645C303030615C30303074}
\BKM@entry{id=74,open,dest={617070656E6469782E41},srcline={1208}}{5C3337365C3337375C303030415C3030305C3034305C303030505C303030725C303030765C3030306E5C3030305C3335355C3030305C3034305C303030705C3030315C3133315C3030305C3335355C3030306C5C3030306F5C303030685C30303061}
\BKM@entry{id=75,open,dest={617070656E6469782E42},srcline={1211}}{5C3337365C3337375C303030425C3030305C3034305C303030445C303030725C303030755C303030685C3030305C3334315C3030305C3034305C303030705C3030315C3133315C3030305C3335355C3030306C5C3030306F5C303030685C30303061}
\BKM@entry{id=76,open,dest={617070656E6469782E43},srcline={1216}}{5C3337365C3337375C303030435C3030305C3034305C3030304F5C303030625C303030735C303030615C303030685C3030305C3034305C303030655C3030306C5C303030655C3030306B5C303030745C303030725C3030306F5C3030306E5C303030695C303030635C3030306B5C3030305C3337355C303030635C303030685C3030305C3034305C303030645C303030615C30303074}
\@writefile{toc}{\contentsline {section}{\numberline {A}První příloha}{49}{appendix.A}\protected@file@percent }
\@writefile{toc}{\contentsline {section}{\numberline {B}Druhá příloha}{49}{appendix.B}\protected@file@percent }
\@writefile{toc}{\contentsline {section}{\numberline {C}Obsah elektronických dat}{49}{appendix.C}\protected@file@percent }
\newlabel{sec:ObsahData}{{C}{49}{Obsah elektronických dat}{appendix.C}{}}
\BKM@entry{id=77,open,dest={73656374696F6E2A2E37},srcline={1269}}{5C3337365C3337375C303030535C303030655C3030307A5C3030306E5C303030615C3030306D5C3030305C3034305C3030307A5C3030306B5C303030725C303030615C303030745C303030655C3030306B}
\BKM@entry{id=77,open,dest={73656374696F6E2A2E37},srcline={1283}}{5C3337365C3337375C303030535C303030655C3030307A5C3030306E5C303030615C3030306D5C3030305C3034305C3030307A5C3030306B5C303030725C303030615C303030745C303030655C3030306B}
\abx@aux@nociteall
\@writefile{toc}{\contentsline {section}{Seznam zkratek}{51}{section*.7}\protected@file@percent }
\BKM@entry{id=78,open,dest={73656374696F6E2A2E38},srcline={1279}}{5C3337365C3337375C3030304C5C303030695C303030745C303030655C303030725C303030615C303030745C303030755C303030725C30303061}
\BKM@entry{id=78,open,dest={73656374696F6E2A2E38},srcline={1293}}{5C3337365C3337375C3030304C5C303030695C303030745C303030655C303030725C303030615C303030745C303030755C303030725C30303061}
\abx@aux@read@bbl@mdfivesum{nobblfile}
\abx@aux@read@bblrerun
\newlabel{LastPage}{{C}{51}{Obsah elektronických dat}{page.51}{}}
+11 -11
View File
@@ -1,18 +1,18 @@
# Fdb version 4
["biber kidiplom"] 1777641420.71466 "kidiplom.bcf" "kidiplom.bbl" "kidiplom" 1785134120.2661 2
"kidiplom.bcf" 1785134120.14143 100507 e04409a00ea07820a76aae942e927593 "pdflatex"
["biber kidiplom"] 1777641420.71466 "kidiplom.bcf" "kidiplom.bbl" "kidiplom" 1785270389.4267 2
"kidiplom.bcf" 1785270389.30231 100507 e04409a00ea07820a76aae942e927593 "pdflatex"
(generated)
"kidiplom.bbl"
"kidiplom.blg"
(rewritten before read)
["makeindex kidiplom.idx"] 1777641420.69393 "kidiplom.idx" "kidiplom.ind" "kidiplom" 1785134120.26338 0
"kidiplom.idx" 1785134118.55941 0 d41d8cd98f00b204e9800998ecf8427e "pdflatex"
["makeindex kidiplom.idx"] 1777641420.69393 "kidiplom.idx" "kidiplom.ind" "kidiplom" 1785270389.4238 0
"kidiplom.idx" 1785270387.66128 0 d41d8cd98f00b204e9800998ecf8427e "pdflatex"
(generated)
"kidiplom.ilg"
"kidiplom.ind"
(rewritten before read)
["pdflatex"] 1785134118.05189 "/home/martin/projects/kidiplom/kidiplom.tex" "kidiplom.pdf" "kidiplom" 1785134120.2635 2
"/home/martin/projects/kidiplom/kidiplom.tex" 1785134117.8614 119164 b5173d7f51966dc96bc4fdcbf6ab2587 ""
["pdflatex"] 1785270387.16211 "/home/martin/projects/kidiplom/kidiplom.tex" "kidiplom.pdf" "kidiplom" 1785270389.42389 2
"/home/martin/projects/kidiplom/kidiplom.tex" 1785270387.05127 120931 9523734fb3e85de527352e4307f3b870 ""
"/usr/share/texmf-dist/fonts/enc/dvips/base/8r.enc" 1775415801 4850 80dc9bab7f31fb78a000ccfed0e27cab ""
"/usr/share/texmf-dist/fonts/enc/dvips/lm/lm-ec.enc" 1775415801 2375 baa924870cfb487815765f9094cf3728 ""
"/usr/share/texmf-dist/fonts/enc/dvips/lm/lm-mathit.enc" 1775415801 2405 5dcf2c1b967ee25cc46c58cd52244aed ""
@@ -259,15 +259,15 @@
"iso.bbx" 1681557593 13233 9f9e9c852fe772bfe1efaacc6b415eb7 ""
"kibase.sty" 1681557593 23853 021ae8236751950ac5e18f6a5bcf1da7 ""
"kidiplom.acr" 0 -1 0 ""
"kidiplom.aux" 1785134120.12543 37335 009208f1c904a01b1a0b56e9772f5e33 "pdflatex"
"kidiplom.aux" 1785270389.2863 37238 bd575a4b780c171f816ec1b9c7d3313a "pdflatex"
"kidiplom.bbl" 0 -1 0 "biber kidiplom"
"kidiplom.cls" 1681557593 18598 7684b2d13ac67d7b017c4eea1e12fa0c ""
"kidiplom.glsdefs" 1777655247.6059 525 791a05cd0a9f8650067804d8f5ff3f41 ""
"kidiplom.ind" 1777641420.71105 0 d41d8cd98f00b204e9800998ecf8427e "makeindex kidiplom.idx"
"kidiplom.lot" 1785134120.14317 142 0f926846b4ca0023532a29a360cf54d1 "pdflatex"
"kidiplom.run.xml" 1785134120.14317 2535 4e001a965ee2f4de88dc6271855a61ea "pdflatex"
"kidiplom.tex" 1785134117.8614 119164 b5173d7f51966dc96bc4fdcbf6ab2587 ""
"kidiplom.toc" 1785134120.14317 6314 b9986ce6cc860b0edabadcbdb37b012e "pdflatex"
"kidiplom.lot" 1785270389.30428 142 0f926846b4ca0023532a29a360cf54d1 "pdflatex"
"kidiplom.run.xml" 1785270389.30428 2535 4e001a965ee2f4de88dc6271855a61ea "pdflatex"
"kidiplom.tex" 1785270387.05127 120931 9523734fb3e85de527352e4307f3b870 ""
"kidiplom.toc" 1785270389.30428 6298 0de76ca124e9009250af8abdb944800b "pdflatex"
(generated)
"kidiplom.acn"
"kidiplom.aux"
+15 -15
View File
@@ -536,16 +536,6 @@ INPUT ./graphics/client-server-architecture.pdf
INPUT ./graphics/client-server-architecture.pdf
INPUT ./graphics/client-server-architecture.pdf
INPUT ./graphics/client-server-architecture.pdf
INPUT ./graphics/grafana.png
INPUT ./graphics/grafana.png
INPUT ./graphics/grafana.png
INPUT ./graphics/grafana.png
INPUT ./graphics/grafana.png
INPUT ./graphics/300playerstrace.png
INPUT ./graphics/300playerstrace.png
INPUT ./graphics/300playerstrace.png
INPUT ./graphics/300playerstrace.png
INPUT ./graphics/300playerstrace.png
INPUT ./graphics/quicr_handshake.pdf
INPUT ./graphics/quicr_handshake.pdf
INPUT ./graphics/quicr_handshake.pdf
@@ -554,6 +544,21 @@ INPUT ./graphics/quicr_handshake.pdf
INPUT /usr/share/texmf-dist/fonts/tfm/adobe/courier/pcrb8t.tfm
INPUT /usr/share/texmf-dist/fonts/vf/adobe/courier/pcrb8t.vf
INPUT /usr/share/texmf-dist/fonts/tfm/adobe/courier/pcrb8r.tfm
INPUT ./graphics/zone_server_architecture.pdf
INPUT ./graphics/zone_server_architecture.pdf
INPUT ./graphics/zone_server_architecture.pdf
INPUT ./graphics/zone_server_architecture.pdf
INPUT ./graphics/zone_server_architecture.pdf
INPUT ./graphics/grafana.png
INPUT ./graphics/grafana.png
INPUT ./graphics/grafana.png
INPUT ./graphics/grafana.png
INPUT ./graphics/grafana.png
INPUT ./graphics/300playerstrace.png
INPUT ./graphics/300playerstrace.png
INPUT ./graphics/300playerstrace.png
INPUT ./graphics/300playerstrace.png
INPUT ./graphics/300playerstrace.png
INPUT ./graphics/latencycomparison.pdf
INPUT ./graphics/latencycomparison.pdf
INPUT ./graphics/latencycomparison.pdf
@@ -583,11 +588,6 @@ INPUT ./graphics/ecs_optimization_tracy_02.png
INPUT ./graphics/ecs_optimization_tracy_02.png
INPUT ./graphics/ecs_optimization_tracy_02.png
INPUT ./graphics/ecs_optimization_tracy_02.png
INPUT ./graphics/zone_server_architecture.pdf
INPUT ./graphics/zone_server_architecture.pdf
INPUT ./graphics/zone_server_architecture.pdf
INPUT ./graphics/zone_server_architecture.pdf
INPUT ./graphics/zone_server_architecture.pdf
INPUT /usr/share/texmf-dist/tex/latex/listings/lstlang1.sty
INPUT /usr/share/texmf-dist/tex/latex/listings/lstlang1.sty
INPUT /usr/share/texmf-dist/tex/latex/listings/lstlang1.sty
+1 -1
View File
@@ -1,5 +1,5 @@
% makeindex style file created by the glossaries package
% for document 'kidiplom' on 2026-7-27
% for document 'kidiplom' on 2026-7-28
actual '?'
encap '|'
level '!'
+123 -108
View File
@@ -1,4 +1,4 @@
This is pdfTeX, Version 3.141592653-2.6-1.40.29 (TeX Live 2026/Arch Linux) (preloaded format=pdflatex 2026.6.8) 27 JUL 2026 08:35
This is pdfTeX, Version 3.141592653-2.6-1.40.29 (TeX Live 2026/Arch Linux) (preloaded format=pdflatex 2026.6.8) 28 JUL 2026 22:26
entering extended mode
restricted \write18 enabled.
%&-line parsing enabled.
@@ -1502,32 +1502,32 @@ Overfull \hbox (0.28238pt too wide) in paragraph at lines 274--275
[]
[12]
<graphics/layer_architecture.png, id=232, 663.47874pt x 321.2pt>
<graphics/layer_architecture.png, id=228, 663.47874pt x 321.2pt>
File: graphics/layer_architecture.png Graphic file (type png)
<use graphics/layer_architecture.png>
Package pdftex.def Info: graphics/layer_architecture.png used on input line 30
8.
(pdftex.def) Requested size: 409.50119pt x 198.24504pt.
[13] [14 <./graphics/layer_architecture.png>]
<graphics/TcpIp.png, id=248, 805.0075pt x 512.91624pt>
<graphics/TcpIp.png, id=244, 805.0075pt x 512.91624pt>
File: graphics/TcpIp.png Graphic file (type png)
<use graphics/TcpIp.png>
Package pdftex.def Info: graphics/TcpIp.png used on input line 342.
(pdftex.def) Requested size: 409.50119pt x 260.91075pt.
[15 <./graphics/TcpIp.png>]
<graphics/http2.pdf, id=255, 275.10779pt x 225.7233pt>
<graphics/http2.pdf, id=251, 275.10779pt x 225.7233pt>
File: graphics/http2.pdf Graphic file (type pdf)
<use graphics/http2.pdf>
Package pdftex.def Info: graphics/http2.pdf used on input line 381.
(pdftex.def) Requested size: 196.5588pt x 161.2807pt.
<graphics/http3.pdf, id=256, 349.305pt x 262.0992pt>
<graphics/http3.pdf, id=252, 349.305pt x 262.0992pt>
File: graphics/http3.pdf Graphic file (type pdf)
<use graphics/http3.pdf>
Package pdftex.def Info: graphics/http3.pdf used on input line 387.
(pdftex.def) Requested size: 196.5588pt x 147.48642pt.
[16] [17 <./graphics/http2.pdf> <./graphics/http3.pdf>] [18] [19]
<graphics/quic_handshake.pdf, id=313, 243.79079pt x 327.14218pt>
<graphics/quic_handshake.pdf, id=309, 243.79079pt x 327.14218pt>
File: graphics/quic_handshake.pdf Graphic file (type pdf)
<use graphics/quic_handshake.pdf>
Package pdftex.def Info: graphics/quic_handshake.pdf used on input line 453.
@@ -1659,7 +1659,7 @@ and I'll forget about whatever was undefined.
Package hyperref Info: bookmark level for unknown lstlisting defaults to 0 on i
nput line 633.
[25] [26]
<graphics/client-server-architecture.pdf, id=369, 609.23605pt x 404.47108pt>
<graphics/client-server-architecture.pdf, id=365, 609.23605pt x 404.47108pt>
File: graphics/client-server-architecture.pdf Graphic file (type pdf)
<use graphics/client-server-architecture.pdf>
Package pdftex.def Info: graphics/client-server-architecture.pdf used on input
@@ -1676,16 +1676,12 @@ spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.
[29]
LaTeX Warning: Reference `sec:quicr' on page 30 undefined on input line 758.
Overfull \hbox (8.12425pt too wide) in paragraph at lines 770--771
Overfull \hbox (8.12425pt too wide) in paragraph at lines 775--776
\T1/lmr/m/n/12 Vytvo°ili jsme t°ídu [][][][], která má na roz-hraní me-tody []
[]
Overfull \hbox (20.39532pt too wide) in paragraph at lines 770--771
Overfull \hbox (20.39532pt too wide) in paragraph at lines 775--776
[][][][][][][][][]\T1/lmr/m/n/12 , [][][][] a [][][][]. První me-toda na-staví
pro kon-cový bod []
[]
@@ -1693,107 +1689,126 @@ pro kon-cov
[30]
LaTeX Warning: Reference `code:entity_spawn_message' on page 31 undefined on in
put line 785.
put line 790.
[31] [32]
<graphics/grafana.png, id=417, 2813.51125pt x 913.4125pt>
File: graphics/grafana.png Graphic file (type png)
<use graphics/grafana.png>
Package pdftex.def Info: graphics/grafana.png used on input line 825.
(pdftex.def) Requested size: 409.50119pt x 132.9362pt.
[33 <./graphics/grafana.png>]
<graphics/300playerstrace.png, id=425, 1348.03625pt x 397.485pt>
File: graphics/300playerstrace.png Graphic file (type png)
<use graphics/300playerstrace.png>
Package pdftex.def Info: graphics/300playerstrace.png used on input line 851.
(pdftex.def) Requested size: 409.50119pt x 120.74449pt.
[34 <./graphics/300playerstrace.png>]
[35]
<graphics/quicr_handshake.pdf, id=439, 337.26pt x 246.9225pt>
[31] [32] [33]
<graphics/quicr_handshake.pdf, id=420, 337.26pt x 246.9225pt>
File: graphics/quicr_handshake.pdf Graphic file (type pdf)
<use graphics/quicr_handshake.pdf>
Package pdftex.def Info: graphics/quicr_handshake.pdf used on input line 932.
Package pdftex.def Info: graphics/quicr_handshake.pdf used on input line 870.
(pdftex.def) Requested size: 409.50119pt x 299.82079pt.
[36] [37 <./graphics/quicr_handshake.pdf>]
Overfull \hbox (3.49525pt too wide) in paragraph at lines 942--943
[34 <./graphics/quicr_handshake.pdf>]
Overfull \hbox (3.49525pt too wide) in paragraph at lines 880--881
[]\T1/lmr/m/n/12 Spolehlivost °e²í kom-po-nenta [][][][], která si udr-ºuje fro
ntu rámc·,
[]
[38]
<graphics/latencycomparison.pdf, id=464, 462.52798pt x 346.89601pt>
File: graphics/latencycomparison.pdf Graphic file (type pdf)
<use graphics/latencycomparison.pdf>
Package pdftex.def Info: graphics/latencycomparison.pdf used on input line 993
.
(pdftex.def) Requested size: 327.60219pt x 245.71564pt.
<graphics/integrationcomparison.pdf, id=465, 462.52798pt x 346.89601pt>
File: graphics/integrationcomparison.pdf Graphic file (type pdf)
<use graphics/integrationcomparison.pdf>
Package pdftex.def Info: graphics/integrationcomparison.pdf used on input line
1001.
(pdftex.def) Requested size: 327.60219pt x 245.71564pt.
[39] [40 <./graphics/latencycomparison.pdf> <./graphics/integrationcomparison.
pdf>]
<graphics/playerbenchmark.png, id=558, 1926.19624pt x 1221.56375pt>
File: graphics/playerbenchmark.png Graphic file (type png)
<use graphics/playerbenchmark.png>
Package pdftex.def Info: graphics/playerbenchmark.png used on input line 1013.
(pdftex.def) Requested size: 204.7506pt x 129.84302pt.
File: graphics/300playerstrace.png Graphic file (type png)
<use graphics/300playerstrace.png>
Package pdftex.def Info: graphics/300playerstrace.png used on input line 1031.
(pdftex.def) Requested size: 409.50119pt x 120.74449pt.
[41 <./graphics/playerbenchmark.png>]
<graphics/ecs_optimization_tracy_01.png, id=567, 1707.37875pt x 472.76625pt>
File: graphics/ecs_optimization_tracy_01.png Graphic file (type png)
<use graphics/ecs_optimization_tracy_01.png>
Package pdftex.def Info: graphics/ecs_optimization_tracy_01.png used on input
line 1042.
(pdftex.def) Requested size: 409.50119pt x 113.38686pt.
<graphics/ecs_optimization_tracy_02.png, id=568, 1196.47pt x 583.17876pt>
File: graphics/ecs_optimization_tracy_02.png Graphic file (type png)
<use graphics/ecs_optimization_tracy_02.png>
Package pdftex.def Info: graphics/ecs_optimization_tracy_02.png used on input
line 1049.
(pdftex.def) Requested size: 409.50119pt x 199.59514pt.
[42 <./graphics/ecs_optimization_tracy_01.png>] [43 <./graphics/ecs_optimizati
on_tracy_02.png>]
Underfull \hbox (badness 10000) in paragraph at lines 1090--1090
[]|\T1/lmr/m/n/12 Název
[]
Underfull \hbox (badness 10000) in paragraph at lines 1094--1094
[]|\T1/lmr/m/n/12 Fixní
[]
Underfull \hbox (badness 10000) in paragraph at lines 1096--1096
[]|\T1/lmr/m/n/12 Hashovací
[]
[44]
Overfull \hbox (6.44025pt too wide) in paragraph at lines 1135--1136
[35]
Overfull \hbox (6.44025pt too wide) in paragraph at lines 951--952
[][][][][][][][][][][][][] \T1/lmr/m/n/12 a [][][][][][][][][][][][][][][][]. K
aºdý
[]
Overfull \hbox (5.32686pt too wide) in paragraph at lines 1139--1140
[]\T1/lmr/m/n/12 Systémovou ar-chi-tek-turu vi-díme na ob-rázku [][]4.10[][]. V
i-díme, ºe []
[]
<graphics/zone_server_architecture.pdf, id=593, 453.61469pt x 298.23419pt>
[36]
<graphics/zone_server_architecture.pdf, id=444, 453.61469pt x 298.23419pt>
File: graphics/zone_server_architecture.pdf Graphic file (type pdf)
<use graphics/zone_server_architecture.pdf>
Package pdftex.def Info: graphics/zone_server_architecture.pdf used on input l
ine 1143.
ine 959.
(pdftex.def) Requested size: 409.50119pt x 269.24106pt.
(/usr/share/texmf-dist/tex/latex/listings/lstlang1.sty
[37 <./graphics/zone_server_architecture.pdf>]
<graphics/grafana.png, id=466, 2813.51125pt x 913.4125pt>
File: graphics/grafana.png Graphic file (type png)
<use graphics/grafana.png>
Package pdftex.def Info: graphics/grafana.png used on input line 994.
(pdftex.def) Requested size: 409.50119pt x 132.9362pt.
[38] [39 <./graphics/grafana.png>]
<graphics/300playerstrace.png, id=478, 1348.03625pt x 397.485pt>
File: graphics/300playerstrace.png Graphic file (type png)
<use graphics/300playerstrace.png>
Package pdftex.def Info: graphics/300playerstrace.png used on input line 1022.
(pdftex.def) Requested size: 409.50119pt x 120.74449pt.
[40 <./graphics/300playerstrace.png>]
<graphics/latencycomparison.pdf, id=486, 462.52798pt x 346.89601pt>
File: graphics/latencycomparison.pdf Graphic file (type pdf)
<use graphics/latencycomparison.pdf>
Package pdftex.def Info: graphics/latencycomparison.pdf used on input line 106
8.
(pdftex.def) Requested size: 327.60219pt x 245.71564pt.
<graphics/integrationcomparison.pdf, id=487, 462.52798pt x 346.89601pt>
File: graphics/integrationcomparison.pdf Graphic file (type pdf)
<use graphics/integrationcomparison.pdf>
Package pdftex.def Info: graphics/integrationcomparison.pdf used on input line
1076.
(pdftex.def) Requested size: 327.60219pt x 245.71564pt.
<graphics/playerbenchmark.png, id=490, 1926.19624pt x 1221.56375pt>
File: graphics/playerbenchmark.png Graphic file (type png)
<use graphics/playerbenchmark.png>
Package pdftex.def Info: graphics/playerbenchmark.png used on input line 1088.
(pdftex.def) Requested size: 204.7506pt x 129.84302pt.
LaTeX Warning: Reference `fig:tracyreplicator' on page 41 undefined on input li
ne 1096.
[41] [42 <./graphics/latencycomparison.pdf> <./graphics/integrationcomparison.p
df>]
File: graphics/300playerstrace.png Graphic file (type png)
<use graphics/300playerstrace.png>
Package pdftex.def Info: graphics/300playerstrace.png used on input line 1100.
(pdftex.def) Requested size: 409.50119pt x 120.74449pt.
LaTeX Warning: Reference `fig:ecs_optimization_tracy_01' on page 43 undefined o
n input line 1107.
[43 <./graphics/playerbenchmark.png>]
<graphics/ecs_optimization_tracy_01.png, id=589, 1707.37875pt x 472.76625pt>
File: graphics/ecs_optimization_tracy_01.png Graphic file (type png)
<use graphics/ecs_optimization_tracy_01.png>
Package pdftex.def Info: graphics/ecs_optimization_tracy_01.png used on input
line 1111.
(pdftex.def) Requested size: 409.50119pt x 113.38686pt.
<graphics/ecs_optimization_tracy_02.png, id=590, 1196.47pt x 583.17876pt>
File: graphics/ecs_optimization_tracy_02.png Graphic file (type png)
<use graphics/ecs_optimization_tracy_02.png>
Package pdftex.def Info: graphics/ecs_optimization_tracy_02.png used on input
line 1118.
(pdftex.def) Requested size: 409.50119pt x 199.59514pt.
LaTeX Warning: Reference `fig:ecs_optimization_tracy_02' on page 44 undefined o
n input line 1123.
LaTeX Warning: Reference `table:serialization_comparison' on page 44 undefined
on input line 1123.
[44 <./graphics/ecs_optimization_tracy_01.png> <./graphics/ecs_optimization_tra
cy_02.png>]
LaTeX Warning: Reference `table:range_query_comparison' on page 45 undefined on
input line 1153.
Underfull \hbox (badness 10000) in paragraph at lines 1159--1159
[]|\T1/lmr/m/n/12 Název
[]
Underfull \hbox (badness 10000) in paragraph at lines 1163--1163
[]|\T1/lmr/m/n/12 Fixní
[]
Underfull \hbox (badness 10000) in paragraph at lines 1165--1165
[]|\T1/lmr/m/n/12 Hashovací
[]
[45] (/usr/share/texmf-dist/tex/latex/listings/lstlang1.sty
File: lstlang1.sty 2025/11/14 1.11b listings language file
)
(/usr/share/texmf-dist/tex/latex/listings/lstlang2.sty
@@ -1813,13 +1828,13 @@ File: lstlang3.sty 2025/11/14 1.11b listings language file
)
(/usr/share/texmf-dist/tex/latex/listings/lstmisc.sty
File: lstmisc.sty 2025/11/14 1.11b (Carsten Heinz)
) [45] [46 <./graphics/zone_server_architecture.pdf>] [47
) [46] [47
] [48
]
LaTeX Font Info: Trying to load font information for TS1+lmr on input line 1
243.
257.
(/usr/share/texmf-dist/tex/latex/lm/ts1lmr.fd
File: ts1lmr.fd 2015/05/01 v1.6.1 Font defs for Latin Modern
@@ -1831,7 +1846,7 @@ No file kidiplom.acr.
]
LaTeX Warning: Empty bibliography on input line 1279.
LaTeX Warning: Empty bibliography on input line 1293.
(./kidiplom.ind)
enddocument/afterlastpage (AED): lastpage setting LastPage.
@@ -1857,10 +1872,10 @@ Package logreq Info: Writing requests to 'kidiplom.run.xml'.
)
Here is how much of TeX's memory you used:
33743 strings out of 469481
635473 string characters out of 5469631
1772286 words of memory out of 5000000
61629 multiletter control sequences out of 15000+600000
33742 strings out of 469481
635456 string characters out of 5469631
1772005 words of memory out of 5000000
61628 multiletter control sequences out of 15000+600000
692285 words of font info for 87 fonts, out of 8000000 for 9000
24 hyphenation exceptions out of 8191
110i,11n,125p,2637b,2312s stack positions out of 10000i,1000n,20000p,200000b,200000s
@@ -1878,10 +1893,10 @@ e1/public/lm/lmri12.pfb></usr/share/texmf-dist/fonts/type1/public/lm/lmri8.pfb>
</usr/share/texmf-dist/fonts/type1/public/lm/lmsy10.pfb></usr/share/texmf-dist/
fonts/type1/urw/courier/ucrb8a.pfb></usr/share/texmf-dist/fonts/type1/urw/couri
er/ucrr8a.pfb>
Output written on kidiplom.pdf (51 pages, 1030690 bytes).
Output written on kidiplom.pdf (51 pages, 1030152 bytes).
PDF statistics:
999 PDF objects out of 1000 (max. 8388607)
790 compressed objects within 8 object streams
992 PDF objects out of 1000 (max. 8388607)
783 compressed objects within 8 object streams
188 named destinations out of 1000 (max. 500000)
722 words of extra memory for PDF output out of 10000 (max. 10000000)
BIN
View File
Binary file not shown.
Binary file not shown.
+163 -149
View File
@@ -581,7 +581,7 @@ Nakonec představíme i architekturu peer-to-peer, kdy umožníme, aby v systém
\subsection{Engine}
Pro hru jsme vyvinuli vlastní herní engine tak, abychom mohli celý systém do hloubky upravovat. V této části popíšeme jeho základní komponenty. Implementace je v jazyce C++, protože je v tomto jazyce napsáno spousty nástrojů a knihoven právě pro vývoj her. Díky tomu se vývoj značně akceleroval. Zároveň je to vhodný jazyk pro práci na nižší úrovni, a to je důležité pro některé metody optimalizace. Engine je implementovaný jako modulární monolit. Jednotlivé moduly představíme.
Pro hru jsme vyvinuli vlastní herní engine tak, abychom mohli celý systém do hloubky upravovat. Implementace je v jazyce C++, protože je v tomto jazyce napsáno spousty nástrojů a knihoven právě pro vývoj her. Díky tomu se vývoj značně akceleroval. Zároveň je to vhodný jazyk pro práci na nižší úrovni, a to je důležité pro některé metody optimalizace. Engine je implementovaný jako modulární monolit.
% Vstupy od hráče -> derivace
% Derivace + Stav -> integrace
@@ -591,14 +591,14 @@ Pro hru jsme vyvinuli vlastní herní engine tak, abychom mohli celý systém do
% Vstup od hráče -> akce
% Co je herní stav, jak probíhá kolo?
Program hry jsme rozdělili na \uv{stav} a \uv{řídící logiku}. Stav obsahuje množinu entit, které jsou ve hře a jejich vlasnosti a atributy. Entity jsou objekty v herním světě, jako postava hráče, truhly s poklady nebo nepřátele. Entita nepřítele může mít vlastnost "množství životů" a truhla vlastnost "poklad", která definuje, co je v truhle obsaženo. Stavu hry se někdy říká pouze \uv{svět}.
Program hry jsme rozdělili na \uv{stav} a \uv{řídící logiku}. Stav obsahuje množinu entit, které jsou ve hře a jejich vlasnosti a atributy. Entity jsou objekty v herním světě, jako postava hráče, nepřátele nebo interaktivní prvky jako truhla s pokladem. Entita má přiřazené vlastnosti, které ji dávají stav. Entita nepřítele může mít vlastnost "množství životů" a truhla vlastnost "poklad", která definuje, co je v truhle obsaženo. Stavu hry se někdy říká pouze \uv{svět}.
% Detaily k implementaci, ale stále dost abstrahované.
% Zmínit svět, ve kterém držíme stav hry. Zmínit derivaci (proces sbírání vstupů, prozatím jen od hráče). Zmínit integraci jako aplikaci derivace na stav.
% Stav hry reprezentujeme kompletně ve třídě \inlcpp{World}. Ta obsahuje registr z knihovny Entt. Řídící logika je ve třídě \inlcpp{WorldController}. Obsahuje smyčku, která v každé iteraci posbírá vstupy od hráče, převede je na akce a aplikuje je společně s další definovanout logikou. Například v naší hře má vstup: stisknutí klávesy W, definovaný příkaz: \uv{posuň dopředu}, která změní vektor zrychlení hráče. Dalšími prvky, které mění změnu stavu je například fyzický engine, který upravuje zrychlení podle nárazů a nebo vlivů sil, například gravitace.
Druhá část je řídící logika, která po iteracích mění stav hry. Tato změna může být pouze na základě stavu světa, například posune objekt, který má nenulový vektor zrychlení. Mimo to může řídící logika reagovat na údalosti. Například stisk tlačítka W je událost, který vyvolá změnu vektoru zrychlení hráče, který tlačítko stiskl. V důsledku toho se postava hráče pohne.
Druhá část je řídící logika, která iterativně mění stav hry. Tato změna může být pouze na základě stavu světa, například posune objekt, který má nenulový vektor zrychlení. Mimo to může řídící logika reagovat na údalosti. Například stisk tlačítka W je událost, který vyvolá změnu vektoru zrychlení hráče, který tlačítko stiskl. V důsledku toho se postava hráče pohne.
Každá iterace řídící logiky trvá přibližně stejně dlouho, většinou 1/60 sekundy nebo 1/24 sekundy. Vyšší frekvence znamená nižší odezvu a lepší plynulost. Nižší frekvence znamená menší výpočetní náročnost. Pro pomalejší hry bez rychlých akčních pasáží se využívá frekvence 24Hz a u kompetentních her i 120Hz.
@@ -705,7 +705,7 @@ Replikátor pracuje pouze s entitami a komponentami. Proto můžeme snapshot zje
Různé entity na serveru jsou pro některé hráče jinak důležité. Například ty, které jsou daleko, nemusíme synchronizovat, protože po vykreslení by nebyly vidět. Komponenta, která se o to stará je \uv{manažer zájmu}.
Obě tyto komponenty, společně se stavem a řídící logikou, jsou ve třídě \texttt{WorldServerController}. Architektura tak využívá komponenty z hry pro jednoho hráče a skrývá distribuovanost pomocí vrstvené architektury.
Obě tyto komponenty, společně se stavem a řídící logikou, jsou ve třídě \inlcpp{WorldServerController}. Architektura tak využívá komponenty ze hry pro jednoho hráče a skrývá distribuovanost pomocí vrstvené architektury.
\subsubsection{Registr klientů}
@@ -741,13 +741,14 @@ Když jsme začali systém měřit, zjistili jsme, že vysoká frekvence replika
\subsubsection{Rollback}
Interpolovat zlepšilo plynulost, ale nepříjemně zvýšilo odezvu mezi vstupem od hráče a vyvolanou změnou stavu. Možným řešením je simulovat řídící logiku i na klientovi, ale pouze pro konkrétní entitu, kterou hráč ovládá. Odezva bude v podstatě nulová, ale navíc bude nižší než před interpolací.
Interpolace zlepšila plynulost, ale nepříjemně zvýšila odezvu mezi vstupem od hráče a vyvolanou změnou stavu. Možným řešením je simulovat řídící logiku i na klientovi, ale pouze pro konkrétní entitu, kterou hráč ovládá. Odezva bude v podstatě nulová.
Vytvořili jsme buffer, do kterého ukládáme konkrétní moment stavu, číslo iterace stavu a seznam akcí, která se v danou iteraci mají aplikovat. Pokud dostaneme snapshot pro snímek $x$ a z bufferu přečteme, jaký byl v iteraci stav. Pokud se neshodují, celý původní stav načteme a opravíme podle snapshotu. Následně znova aplikujeme všechny akce a přepíšeme tak náš buffer, až se dostaneme do aktuální iterace. Poté normálně pokračujeme s opraveným stavem.
\subsection{Posílání zpráv}
% Popis našeho middleware pro posílání zpráv.
@@ -755,7 +756,11 @@ Vytvořili jsme buffer, do kterého ukládáme konkrétní moment stavu, číslo
% Měl by poskytovat možnost, jak posílat zprávy nespolehlivě.
% Zpráva přijde vždy buď celá, nebo vůbec.
Popíšeme náš middleware pro posílání zpráv a jeho protokol založený na TCP. Poskytuje službu oboustranného peer-to-peer posílání zpráv na různé koncové body, které jsou identifikované čtyř bytovým číslem. Strana může pro libovolný identifikátor definovat handler, který se po získání takové zprávy spustí. Protokol zajišťuje spolehlivost na úrovni zpráv. To znamená, že zpráva dorazí buď celá, nebo vůbec. Později v kapitole \ref{sec:quicr} představíme náš protokol v transportní vrstvě, který umožňuje posílat zprávy spolehlivě i nespolehlivě.
V aplikační vrstvě jsme definovali middleware protokol, který umožňuje obousměrné posílání typovaných zpráv. Typ zprávy je definován čtyř bytovým kladným číslem. Protokol jsme umístili do modulu \inlcpp{message_protocol}. Protokol využívá TCP, ale později implementaci změníme tak, aby používal náš protokol.
Pro navázání spojení musejí obě strany vytvořit objekt
% Popíšeme náš middleware pro posílání zpráv a jeho protokol založený na TCP. Poskytuje službu oboustranného peer-to-peer posílání zpráv na různé koncové body, které jsou identifikované čtyř bytovým číslem. Strana může pro libovolný identifikátor definovat handler, který se po získání takové zprávy spustí. Protokol zajišťuje spolehlivost na úrovni zpráv. To znamená, že zpráva dorazí buď celá, nebo vůbec. Později v kapitole \ref{sec:quicr} představíme náš protokol v transportní vrstvě, který umožňuje posílat zprávy spolehlivě i nespolehlivě.
\subsubsection{Kódování zpráv}
@@ -804,95 +809,28 @@ Posledním příkladem je Cap'n'Proto, čteno Captain Proto. Je to volně dostup
\subsection{Metriky}
Představíme metody měřění a metriky v systému, které jsme využili pro hledání potenciálních míst pro optimalizaci. Pro sbírání metrik je třeba mít úložistě, kam budeme metriky ukládat a rozhraní, přes které je budeme vizualizovat. Úložiště může být například CSV soubor nebo relační databáze. Existují optimalizované databáze pro vkládání dat s časovou známkou, kterým se říká \uv{timescale}. Jsou ideální právě pro metriky nebo logy, protože narozdíl od klasických databází jsou optimalizované pro rychlé vkládání. Rozhodli jsme se použít relační databázi \uv{PostgreSQL} s rozšířením \uv{TimescaleDB}. Pro vizualizaci jsme použili službu \uv{Grafana}, která umí z TimescaleDB číst. Všechny tyto služby popíšeme v následujících částech.
\subsubsection{PostgreSQL}
Populární relační databáze je PostgreSQL. Rozhodli jsme se právě pro tu, protože je to otevřený a svobodný software zdarma. Lze si ho snadno nasadit lokálně, ať už daemoném nebo jako Docker kontejner. Skrze rozšíření jako TimescaleDB lze přidat podporu a optimalizace pro různé použití. V našem případě se chceme ukládat informace o hráčích a stav světa pro perzistenci a metriky. Informace o hráčích a stav světa zvládne bez problémů v základní verzi. Pro metriky použijeme zmíněné rozšíření.
\subsubsection{TimescaleDB}
Pro optimalizaci PostgreSQL pro časová data jsme zvolili TimescaleDB. Díky tomu, že se jedná o rozšíření, nemusíme spravovat jinou službu, než PostgreSQL. TimescaleDB umožňuje vytvářet tzv. hypertables, které jsou optimalizované pro rychlé vkládání. Vytvořili jsme komponentu \inlcpp{NetworkMetricsReporter}, která má na rozhraní různé metody pro získávání metrik. Např. \inlcpp{report\_outbound} a \inlcpp{report\_inbound}. Tyto údaje posílá do komponenty \inlcpp{TimescaleDbWriter}. To je konkrétní implementace pro TimescaleDB, které má na rozhraní metodu \inlcpp{report(metric\_name, value)}. V rámci optimalizace si \inlcpp{NetworkMetricsReporter} metriky ukládá do bufferu, který až pomocí metody \inlcpp{flush} odešle do databáze. To se neděje nutně po každé metrice, ale v našem případě si reportér ukládá hodnoty do bufferu a po intervalech je vkládá do databáze.
\subsubsection{Grafana}
Grafana je služba, která skrze webovou stránku poskytuje rozhraní pro vizualizaci metrik. Lze nastavit svůj dashboard a v něm různé grafy. Pro naše účely jsme vytvořili grafy pro odchozí a příchozí množství bytů. Služba slouží spíše pro sledování stavu a neumožňuje pokročilejší analýzu.
\begin{figure}
\begin{center}
\includegraphics[width=1\textwidth]{graphics/grafana.png}
\end{center}
\caption{Příklad Grafana dashboardu}
\label{fig:grafana}
\end{figure}
\subsubsection{Orchestrace}
Popíšeme, jak jsme všechny služby zprovoznili a nastavili. Podrobněji se na orchestraci podíváme později.
\subsubsection{ImGui}
Pro uživatelské rozhraní jsme použili knihovnu ImGui a ImPlot. Tyto knihovny využívají pro vykreslování grafickou kartu a snadno se dali integrovat do našeho vykreslovacího enginu. Knihovna funguje procedurálně, nikoliv objektově. Každý snímek, který vykreslujeme, musíme celé rozhraní definovat znova. To uděláme pomocí volání funkcí. Nejprve zavoláme funkci \inlcpp{Begin("Název okna")}, která zobrazí okno, do kterého můžeme vložit další prvky, jako texty, textové vstupy, nebo tlačítka. Tento přístup je pro herní enginy a podobné kreativní aplikace ideální, protože umožňuje velmi snadno a rychle dělat dynamické uživatelské rozhraní.
Knihovnu jsme využili pro vykreslení metrik přímo uživateli klienta.
\subsubsection{Tracy}
Pro měření a pokročilejší analýzu výkonu programu klienta nebo serveru používám profiler Tracy. Je zdarma, open-source, napsaný v C++ a pro vykreslování UI využívá ImGui. Poskytuje přesnost na nanosekundy, což je užitečné u serverů, na kterém může být miliony různých entity. Navíc umožňuje připojit se k programu, který měří, vzdáleně. Případně sbírat metriky do souboru, ten si ze serveru stáhnout a analyzovat později.
V kódu umožňuje definovat jednotlivé iterace řídící logiky zvané snímky. Následně umožňuje definovat tzv. \uv{zóny}, které následně měří. Zóna může být průběh funkce nebo její konkrétní část. Na obrázku \ref{fig:frame_in_tracy} vidíme, jak taková analýza vypadá. Vidíme právě jeden snímek. V něm máme označené části replikátoru a manažera zájmu. Také vidíme dole zóny.
\begin{figure}
\begin{center}
\includegraphics[width=1\textwidth]{graphics/300playerstrace.png}
\end{center}
\caption{Jeden snímek v Tracy}
\label{fig:frame_in_tracy}
\end{figure}
\subsubsection{Konkrétní metriky}
Vyjmenujeme metriky, které budeme měřit. Je dobré zmínit, že místo, ze kterého budeme metriky sbírat, je server.
\begin{description}
\item[{Inbound/Outbound bandwidth}] \hfill \\
Nejpřirozenější metrika je příchozí a odchozí množství dat v bytech. Už zde pro mě bylo nutné si uvědomit důležitost oddělit vrstvu, která kóduje a dekóduje zprávy, od zbytku. Přesně na tomto místě totiž budu metriky dělat. Metriku budu sčítat.
\item[{Odezva}] \hfill \\
Budu měřit odezvu mezi odesláním vstupu od klienta pro snímek x a odpovědí od serveru pro snímek x. Tuto metriku budu průměrovat.
\item[{Počet snímků za vteřinu}] \hfill \\
Ze začátku se mi stávalo, že uzké hrdlo nebyla síť, ale síťová vrstva v aplikaci, která třeba dlouho skládala zprávy. Proto si udržuju i přehled o počtu snímků, které server stíhá. Podle toho se lze orientovat při výběru hardware pro server.
\end{description}
\subsubsection{Sbírání v reálném čase}
Přímo v hráčově klientské aplikaci jsme chtěli mít možnost vidět metriky v reálném čase. Do síťové vrstvy jsme přidali komponentu pro reportování událostí a jejich metrik zvanou \inlcpp{NetworkMetricReporter}, která obsahuje metody jako \inlcpp{report\_inbound} a \inlcpp{report\_outbound}. První metoda hlásí příchozí byty a druhá odchozí.
\subsection{Protokol QUICr}
Naše hra používala ke komunikaci mezi vrcholy protokol TCP. Zmínili jsme ale, že ten pro hry nemusí být vhodný. Vytvořil jsme vlastní protokol inspirovaný QUIC, který využívá UDP, ale upustili jsme podmínky pro spolehlivost, konkrétně jistotu doručení a uspořádání zpráv. Nakonec jsme TPC a QUICr porovnali, abychom se o optimalizaci přesvědčili.
Naše hra používala ke komunikaci mezi vrcholy protokol TCP. Zmínili jsme ale, že ten pro hry nemusí být vhodný. Vytvořili jsme vlastní protokol inspirovaný QUIC, který využívá UDP, ale uvolnili jsme podmínky pro spolehlivost, konkrétně jistotu doručení a uspořádání zpráv. Spolehlivost a uspořádání lze definovat pro každou zprávu zvlášť. V další kapitole TCP a QUICr porovnáme a ukážeme, jak se výhody QUICr projeví.
Protokol je obousměrný proud paketů se spolehlivými a nespolehlivými rámci využívající UDP. Jeden poslaný UDP datagram může mít více paketů. Rámce můžeme rozdělit na dva typy: datové a ovládací. Ovládací slouží pro handshake, ukončení spojení nebo nastavení jiných parametrů spojení a budou vždy spolehlivě doručené. Datové obsahují aplikační data a mohou definovat svou spolehlivost. Ty, které budou obsahovat pozice hráčů, tak budeme moct odesílat nespolehlivě, zatímco změny stavu, jako měna mesh, posíláme spolehlivě. Architektura se skládá ze dvou komponent: \uv{koncový bod} a \uv{spojení}.
Protokol je obousměrný proud paketů se spolehlivými a nespolehlivými rámci využívající UDP. Jeden poslaný UDP datagram může mít více rámců. Rámce jsme rozdělili na dva typy: datové a ovládací. Ovládací slouží pro handshake, ukončení spojení nebo nastavení jiných parametrů spojení a budou vždy doručené spolehlivě. Datové rámce obsahují aplikační data a mohou definovat svou spolehlivost. Ty, které budou obsahovat pozice hráčů, tak budeme moct odesílat nespolehlivě, zatímco změny stavu, jako změna barvy postavy, posíláme spolehlivě. Implementace se skládá ze dvou tříd: \uv{koncový bod} a \uv{spojení}.
Koncový bod se stará o soket pro UDP: čtení a zápis na něj, a udržuje si registr navázaných spojení. Při přečtení datagramu, který splňuje formát, ho správně nasměruje podle registru. Nechtěli jsme, aby si implementace QUICr spravovala vlastní asynchronní kontext. Namísto toho jsme definovali metodu pro ťik, která posbírá zprávy od jednotlivých navázaných spojení a pošle je. Následně přečte všechna data ze soketu a roztřídí je do navázaných spojení.
Objekt navázaného spojení je stavový stroj a fronta příchozích a fronta odchozích zpráv, podobně jako TCP spojení. Stavy se mění v reakci na příchozí ovládací rámce. Každý objekt spojení má přiřazeno alespoň jedno ID reprezentované osmi bytovým číslem. Tento objekt přímo nepracuje se socketem, ale poskytuje rozhraní, kterým dostává získané zprávy, které odeslala druhá strana. Právě tento objekt překládá n-tici bytů na rámce a postupně je zpracovává. Stavový stroj je důležitý hlavně v procesu handshake, který definujeme níže.
Objekt navázaného spojení je stavový stroj a fronta příchozích a fronta odchozích zpráv, podobně jako TCP spojení. Stavy se mění v reakci na příchozí kontrolní rámce. Jeden objekt navázaného spojení může mít přiřazených více ID. Tento objekt si datagram přečte a přeloží na pakety a rámce. Ty postupně prochází. Stavový stroj bude důležitý hlavně v procesu handshake, který definujeme níže.
Objekt pro koncový bod se stará o soket pro UDP: čtení a zápis na něj, a udržuje si registr objektů spojení. Při získání datagramu ze socketu ověří, že má správný formát. Podle protokolu by každý datagram měl obsahovat hlavičku s magickým číslem a ID spojení. Koncový bod přečte ID spojení a podle svého registru vyhledá objekt spojení, kterému tělo zprávy předá. Pokud v registru klíč pro získané ID není, koncový bod si objekt spojení vytvoří v počátečním stavu a začíná proces zvaný handshake. Tento proces popíšeme v kapitole TODO
\subsubsection{Rámec}
Nechtěli jsme, aby si implementace QUICr spravovala vlastní asynchronní kontext. Namísto toho jsme definovali metodu pro aktualizaci, která posbírá zprávy od jednotlivých navázaných spojení a pošle je. Následně přečte všechna data ze soketu a roztřídí je do navázaných spojení.
Hlavním prvkem protokolu jsou právě rámce. Jak už bylo nastíněno, dělíme je na kontrolní a datové. Pro využití nespolehlivosti jsme u každého datového rámce umožňili definovat, jestli je spolehlivý nebo nespolehlivý. O spolehlivost obecně se stará komponenta \inlcpp{ReliabilityUnit}, kterou podpobněji představíme v kapitole \ref{sec:quicr_reliability}.
\subsubsection{Rámce}
Hlavním prvkem datového přenosu v protokolu jsou rámce. Jak už bylo nastíněno, dělíme je na kontrolní a datové. Pro využití nespolehlivosti jsme u každého datového rámce umožňili definovat, jestli je spolehlivý nebo nespolehlivý. O spolehlivost obecně se stará komponenta \inlcpp{ReliabilityUnit}, kterou podpobněji představíme v kapitole \ref{sec:quicr_reliability}.
Rámec je n-tice bytů, která se skládá z hlavičky a těla. V hlavičce máme ID cílového spojení a ID počátečního spojení.
% U UDP je další problém, a to ten, že když implementuju připojení pro UDP, tak všechny datagramy budou chodit na socket, na kterém poslouchám. Když budu ze socketu číst, dostanu libovolný datagram, který zrovna přišel, společně s adresou, ze které přišel. Tuto adresu přečtu z IP hlavičky, která není zašifrovaná, a tudíž ji kdokoliv může zfalšovat. Tomu se říká tzv. IP spoofing. Tento útok je poměrně slabý, protože v případě odpovědi budu stále odesílat data zpět na správnou adresu. Útok může sloužit například pro poslání požadavku na odpojení, nebo posílat jiné vstupy. Jedná se tedy spíše o neškodný ale otravný charakter útoku.
@@ -903,7 +841,7 @@ Hlavním prvkem protokolu jsou právě rámce. Jak už bylo nastíněno, dělím
\subsubsection{Handshake}
Objekt navázaného spojení obsahuje stavový stroj a postupně mezi stavy přechází. Počáteční stav je \inlcpp{Closed}. Jedna strana musí začít a odeslat paket s \inlcpp{Hello} rámcem. Po obdržení se stavový stroj druhé strany přesune do \inlcpp{ReceivedHello} a spolehlivě odešle \inlcpp{Hello}. Když strana dostane rámec \inlcpp{Hello} tak ví, že v hlavičce paketu je cílové i lokální ID. Proto už touto výměnou se strany shodli na ID navázaného spojení, které budou používat. Poté už si vymění rámec \inlcpp{HandshakeDone} a spojení je navázané a připravené k posílání.Celý stavový diagram vidíme na obrázku \ref{fig:quicr_handshake}.
Objekt navázaného spojení obsahuje stavový stroj a postupně mezi stavy přechází. Počáteční stav je \inlcpp{Closed}. Jedna strana musí začít a odeslat paket s \inlcpp{Hello} rámcem. Po obdržení se stavový stroj druhé strany přesune do \inlcpp{ReceivedHello} a spolehlivě odešle \inlcpp{Hello}. Když strana dostane rámec \inlcpp{Hello} tak ví, že v hlavičce paketu je cílové i lokální ID. Proto už touto výměnou se strany shodli na ID navázaného spojení, které budou používat. Poté už si vymění rámec \inlcpp{HandshakeDone} a spojení je navázané a připravené k posílání.C elý stavový diagram vidíme na obrázku \ref{fig:quicr_handshake}.
% Nové připojení projde všechny rámce v paketu. Měl by narazit na rámec Hello, který když najde, a je ve stavu `Initial`, tak z hlavičky zjistí unikátní ID druhé strany a uloží si ho. Reaguje na rámec tak, že druhé straně odešle přes koncový bod paket, který obsahuje: rámec ACK o tom, že paket s číslem přijal, a rámec Hello. ACK si pro začátek představme zakódovaný jako: první 4 byty reprezentují kladné celé číslo pro počet rámců, řekněme $n$, které chceme označit jako přijaté. Následně přečteme $4n$ bytů. Každé 4 byty představují číslo paketu, který označíme jako ACKed. Jednotce, která udržuje stav o tom, jaké pakety jsou potřeba oznámit jako ACK a které je třeba poslat znovu, budu říkat `RealiabilityUnit` a podrobněji ji rozeberu později.
@@ -959,9 +897,10 @@ Spolehlivost řeší komponenta \inlcpp{ReliabilityUnit}, která si udržuje fro
\subsubsection{Enkodér}
Pro kódování jsme vytvořili komponentu \inlcpp{QuicrEncoder}, která přes rozhraní umožňuje kódovat pakety a rámce do libovolné alokované paměti. Specifická vlastnost, kterou jsme potřebovali, je kódovat, dokud je v bufferu místo. Pokud zbývá $r$ bytů místa a replikátor by chtěl zakódovat rámec, který má $> r$ bytů, musí metoda vrátit informaci o neúspěchu, ale nevyhazovat vyjímku, ani neposunovat kurzor. Důvodem je, že UDP je nad protokolem IP, který může začít fragmentovat datagramy. Proto se většina protokolů snaží držet velikost datagramů kolem 1200 bytů. Podobný přístup jsme adaptovali my.
Pro kódování jsme vytvořili třídu \inlcpp{QuicrEncoder}, která přes rozhraní umožňuje kódovat pakety a rámce do libovolné alokované paměti. Specifická vlastnost, kterou jsme potřebovali, je kódovat, dokud je v bufferu místo. Pokud zbývá $r$ bytů místa a replikátor by chtěl zakódovat rámec, který má $> r$ bytů, musí metoda vrátit informaci o neúspěchu, ale nevyhazovat vyjímku, ani neposunovat kurzor. Důvodem je, že UDP je nad protokolem IP, který může začít fragmentovat datagramy. Proto se většina protokolů snaží držet velikost datagramů kolem 1200 bytů.
Dále musel umožňovat zakódovat hodnotu zpětně, jako například délku, kterou kvůli omezení bufferu víme až později. Potom, co přes rozhraní zapíšeme vše, co je potřeba, zavoláme metodu \inlcpp{finish}, která hodnoty pro délku přenastaví na správnou hodnotu.
Další problém, který musel enkodér řešit, bylo zpětně zapsat hodnoty do hlavičky. Na začátku zápisu, kdy zapisuje do hlavičky, tak ještě není známá velikost těla, která je ale potřebný atribut v hlavičce. Proto se zapisuje zpětně.
% Dále musel umožňovat zakódovat hodnotu zpětně, jako například délku, kterou kvůli omezení bufferu víme až později. Potom, co přes rozhraní zapíšeme vše, co je potřeba, zavoláme metodu \inlcpp{finish}, která hodnoty pro délku přenastaví na správnou hodnotu.
\subsubsection{Testování}
@@ -971,7 +910,143 @@ Při implementaci jsme zjistili, že je dobré začít testy, které definují j
% Popsal jsem problémy, které jsem potřeboval vyřešit. Představím protokol, který je pro mě řeší. Vytvořil jsem třídu `QuicrConnection`, která bude reprezentovat stavový stroj připojení a zároveň umožní číst a zapisovat. Rozhodl jsem se, že zapisovat bude zprávy, nikoliv pouze proud bytů. Proto jsem použil tzv. message frame. Pokud něco popnu z QuicrConnection, je to vždy celá zpráva, která přišla. Stejný princip používá i ZeroMQ. Vytvořil jsem dvě třídy: QuicrConnection a QuicrConnectionListener. QuicrConnection obsahuje stavový stroj připojení a rozhraní pro příjímání a odesílání zpráv. QuicrConnectionListener obsahuje rozhraní pro poslouchání nově příchozích spojení. Nasluchač bude spravovat UDP socket. Když přijde nový datagram z adresy, kterou ještě nezná, a přišla zpráva Hello, tak si do seznamu přidá připojení ve stavu HelloReceived. Při datagramu z adresy, kterou zná, pošle tento datagram přímo do spojení na spracování. Každé spojení si bude udržovat svoji frontu příchozích zpráv.
\subsubsection{Měření}
% \subsection{Optimalizace QUICr}
% \subsubsection{Šifrování}
% Jednotlivé datagramy a zprávy je třeba šifrovat a pro to je třeba, aby si dvě strany vyměnili tajný klíč. Představím metodu, kterou pro výměnu budu využívat.
% \subsubsection{SPR-6}
% Metodu, kterou jsem viděl například u síťového protokolu pro hru World Of Warcraft je SRP-6. Jedná se o protokol, který nevyžaduje, aby server znal heslo klienta, ale měl u sebe pouze validátor, a klient mu díky němu dokáže, že heslo zná. Pro tento přístup je třeba udělat handshake.
\subsubsection{Congestion control}
\subsubsection{Bandwidth control}
Entity, které jsou od hráče daleko, není třeba aktualizovat tak často jako ty, které jsou k němu blízko. Již jsme nastínili, že můžeme můžeme spočítat důležitost jednotlivých entit pro klienta a omezit tak počet entit, které musí replikátor synchronizovat. Například můžeme vzdálenější entity synchronizovat méně často. Důležité je, aby se i ty dostali někdy na řadu.
\subsection{Sharding}
Proces, při kterém hráče rozdělíme do skupin, které se navzájem nevidí, i když jsou na stejném serveru blízko sebe, se říká sharding. Podobný princip funguje i v databázích.
\subsection{Horizontální škálování}
Další z metod podobná shardování, je \uv{horizontální škálování}, kdy do systému přidáváme servery, které si tak rovnoměrně rozdělí práci. V případě naší hry jsme rozdělili herní svět na zóny a o každou se stará jiný server. Takový server je \uv{zone server} a dohromady tvoří \uv{zone cluster}. Do systému jsme dále přidali \uv{cluster koordinátora}, který říká, který zone server má jakou zónu. Model mezi koordinátorem a zone serverem je klient-server. Na druhou stranu zone servery mezi sebou komunikují přímo a využívají model peer-to-peer.
Představíme, jak spolu zone servery komunikují. Využijeme k tomu už existující komponenty: replikátor a manažera zájmu. Nejprve jsme stav hry, manažera zájmu a fyzický svět do třídy \inlcpp{ZoneManager}. Tuto třídu obalíme \inlcpp{ZoneServer} třídou. Ta bude obsahovat replikátor a \inlcpp{ZoneCoordinatorClient}. Manažer zón si bude udržovat registr sousedních zón a bude se k ním chovat jako klasickým klientům. Rozdíl bude ten, že klient má jako zájem definovaný pouze bod a manažer zájmu klientovi přiřadí do zájmu entity, které jsou od bodu v dostatečné vzdálenosti. Sousedi budou mít jako zájem definovanou celou jejich plochu. Manažer zájmu má nyní na rozhraní dvě metody: \inlcpp{register\_client\_interest(interest\_id, entity)} a \inlcpp{register\_zone\_interest(interest\_id, area)}. Každý zájem je definovaný unikátním ID. O to, jaké entity pak konkrétní zájem zajímají získáme voláním \inlcpp{get_interest(interest_id)}.
Replikátor poté replikuje sousedům ty entity, které jsou od plochy souseda v dostatečné blízkosti. Pokud klient překročí do jiné zóny, měl by manažer zóny předat klienta druhé zóně. Toto modelujeme přes \inlcpp{ZoneProxy}, která reprezentuje souseda pro manažera konkrétní zóny. Implementace obsahuje \inlcpp{ZoneClusterLink}, která obsahuje QUICr endpoint, na který ostatní zóny mohou posílat cluster data.
Systémovou architekturu vidíme na obrázku \ref{fig:zone_cluster_architecture}. Vidíme, že \inlcpp{ZoneClusterLink} slouží pro komunikaci mezi servery v clusteru a zároveň pro replikaci entit, které jsou blízko hranic se sousední zónou. Když se nový server spustí, nejprve se registruje koordinátorovi. Ten mu přiřadí ID, plochu a seznam jeho sousedů včetně \inlcpp{ZoneClusterLink} adres. S každým sousedem přes QUICr naváže spojení a představí se pomocí zprávy \inlcpp{ZoneHello}. Tím si ho druhý server přidá do registru a může na něj začít přenášet klienty.
\begin{figure}
\centering
\includegraphics[width=1\textwidth]{graphics/zone_server_architecture.pdf}
\label{fig:zone_cluster_architecture}
\caption{Architektura systému s zone clusterem}
\end{figure}
\section{Výsledná hra}
V této kapitole představíme hru.
\section{Měřění}
\subsection{Metriky}
Představíme metody měřění a metriky v systému, které jsme využili pro hledání potenciálních míst pro optimalizaci. Pro sbírání metrik je třeba mít úložistě, kam budeme metriky ukládat a rozhraní, přes které je budeme vizualizovat. Úložiště může být například CSV soubor nebo relační databáze. Existují optimalizované databáze pro vkládání dat s časovou známkou, kterým se říká \uv{timescale}. Jsou ideální právě pro metriky nebo logy, protože narozdíl od klasických databází jsou optimalizované pro rychlé vkládání. Rozhodli jsme se použít relační databázi \uv{PostgreSQL} s rozšířením \uv{TimescaleDB}. Pro vizualizaci jsme použili službu \uv{Grafana}, která umí z TimescaleDB číst. Všechny tyto služby popíšeme v následujících částech.
\subsubsection{PostgreSQL}
Populární relační databáze je PostgreSQL. Rozhodli jsme se právě pro tu, protože je to otevřený a svobodný software zdarma. Lze si ho snadno nasadit lokálně, ať už daemoném nebo jako Docker kontejner. Skrze rozšíření jako TimescaleDB lze přidat podporu a optimalizace pro různé použití. V našem případě se chceme ukládat informace o hráčích a stav světa pro perzistenci a metriky. Informace o hráčích a stav světa zvládne bez problémů v základní verzi. Pro metriky použijeme zmíněné rozšíření.
\subsubsection{TimescaleDB}
Pro optimalizaci PostgreSQL pro časová data jsme zvolili TimescaleDB. Díky tomu, že se jedná o rozšíření, nemusíme spravovat jinou službu, než PostgreSQL. TimescaleDB umožňuje vytvářet tzv. hypertables, které jsou optimalizované pro rychlé vkládání. Vytvořili jsme komponentu \inlcpp{NetworkMetricsReporter}, která má na rozhraní různé metody pro získávání metrik. Např. \inlcpp{report\_outbound} a \inlcpp{report\_inbound}. Tyto údaje posílá do komponenty \inlcpp{TimescaleDbWriter}. To je konkrétní implementace pro TimescaleDB, které má na rozhraní metodu \inlcpp{report(metric\_name, value)}. V rámci optimalizace si \inlcpp{NetworkMetricsReporter} metriky ukládá do bufferu, který až pomocí metody \inlcpp{flush} odešle do databáze. To se neděje nutně po každé metrice, ale v našem případě si reportér ukládá hodnoty do bufferu a po intervalech je vkládá do databáze.
\subsubsection{Grafana}
Grafana je služba, která skrze webovou stránku poskytuje rozhraní pro vizualizaci metrik. Lze nastavit svůj dashboard a v něm různé grafy. Pro naše účely jsme vytvořili grafy pro odchozí a příchozí množství bytů. Služba slouží spíše pro sledování stavu a neumožňuje pokročilejší analýzu.
\begin{figure}
\begin{center}
\includegraphics[width=1\textwidth]{graphics/grafana.png}
\end{center}
\caption{Příklad Grafana dashboardu}
\label{fig:grafana}
\end{figure}
\subsubsection{Orchestrace}
Popíšeme, jak jsme všechny služby zprovoznili a nastavili. Podrobněji se na orchestraci podíváme později.
\subsubsection{ImGui}
Některé metriky jsme chtěli zobrazit přímo v klientovi pro hru. Jsou to například příchozí a odchozí množství dat klienta. Tyto data neukládáme nikam do databáze a musíme si je spravovat lokálně. Pro zobrazení uživatelského rozhraní jsme zvolili knihovnu ImGui a ImPlot, které se integrují přímo do vykreslovacího enginu. Pro knihovnu jsme přidali jednu novou úlohu do vykreslovacího grafu.
S knihovnou se pracuje procedurálně, nikoliv objektově. Každý snímek je třeba definovat celé rozhraní znova. Pro definici voláme různé funkce, kde každá definuje v rozhraní některý z možných prvků. Například funkce \inlcpp{InputText} zobrazí vstup pro text. Důležitá je funkce \inlcpp{Begin("Název okna")}, která zobrazí okno, do kterého můžeme vložit další prvky, jako texty, textové vstupy, nebo tlačítka. Tento přístup je pro herní enginy a podobné kreativní aplikace ideální, protože umožňuje velmi snadno a rychle dělat dynamické uživatelské rozhraní.
\subsubsection{Tracy}
Pro měření a pokročilejší analýzu výkonu programu klienta nebo serveru používáme profiler Tracy. Tento program umožňuje v našem programu definovat tzv. zóny: úsek po sobě jdoucích instrukcí, u kterých měří dobu jejich běhu.
Je zdarma, open-source, napsaný v C++ a pro vykreslování UI využívá ImGui. Poskytuje přesnost na nanosekundy, což je užitečné u serverů, na kterém může být miliony různých entity. Navíc umožňuje připojit se k programu, který měří, vzdáleně. Případně sbírat metriky do souboru, ten si ze serveru stáhnout a analyzovat později.
V kódu umožňuje definovat jednotlivé iterace řídící logiky zvané snímky. Následně umožňuje definovat tzv. \uv{zóny}, které následně měří. Zóna může být průběh funkce nebo její konkrétní část. Na obrázku \ref{fig:frame_in_tracy} vidíme, jak taková analýza vypadá. Vidíme právě jeden snímek. V něm máme označené části replikátoru a manažera zájmu. Také vidíme dole zóny.
\begin{figure}
\begin{center}
\includegraphics[width=1\textwidth]{graphics/300playerstrace.png}
\end{center}
\caption{Jeden snímek v Tracy}
\label{fig:frame_in_tracy}
\end{figure}
\subsubsection{Konkrétní metriky}
Vyjmenujeme metriky, které budeme měřit. Je dobré zmínit, že místo, ze kterého budeme metriky sbírat, je server.
\begin{description}
\item[{Inbound/Outbound bandwidth}] \hfill \\
Nejpřirozenější metrika je příchozí a odchozí množství dat v bytech. Už zde pro mě bylo nutné si uvědomit důležitost oddělit vrstvu, která kóduje a dekóduje zprávy, od zbytku. Přesně na tomto místě totiž budu metriky dělat. Metriku budu sčítat.
\item[{Odezva}] \hfill \\
Budu měřit odezvu mezi odesláním vstupu od klienta pro snímek x a odpovědí od serveru pro snímek x. Tuto metriku budu průměrovat.
\item[{Počet snímků za vteřinu}] \hfill \\
Ze začátku se mi stávalo, že uzké hrdlo nebyla síť, ale síťová vrstva v aplikaci, která třeba dlouho skládala zprávy. Proto si udržuju i přehled o počtu snímků, které server stíhá. Podle toho se lze orientovat při výběru hardware pro server.
\end{description}
\subsubsection{Sbírání v reálném čase}
Přímo v hráčově klientské aplikaci jsme chtěli mít možnost vidět metriky v reálném čase. Do síťové vrstvy jsme přidali komponentu pro reportování událostí a jejich metrik zvanou \inlcpp{NetworkMetricReporter}, která obsahuje metody jako \inlcpp{report\_inbound} a \inlcpp{report\_outbound}. První metoda hlásí příchozí byty a druhá odchozí.
\subsection{QUICr}
Protokol měl za cíl snížit odezvu na nespolehlivé síti a neblokovat zprávy. Vytvořili jsme test, který simuluje program hry. V testu jsou dvě vlákna, jedno pro klienta a druhé pro server. Oba mají svou vlastní smyčku, ve kterém iterují. Klient odesílá hodnotu derivace typu double. Server si udržuje stav hodnoty, nazvěme ji \uv{pozice}. Při obdržení derivace ji přičte k aktuálnímu stavu. Každý snímek server odesílá na klienta stav pozice, kterou si klient aplikuje.
@@ -1016,12 +1091,6 @@ Nakonec jsme integrovali protokol přímo do replikátoru. Vytvořili jsme simul
\end{figure}
\subsection{Optimalizace replikátoru}
Test s 301 hráči odhalil nedostatečný výkon serveru. Pomocí Tracy jsme začali program analyzovat. Na obrázku \ref{fig:tracyreplicator} vidíme, že pouze aktualizace replikátoru trvá každý snímek kolem 100ms. Pro představu, pokud bychom chtěli, aby server integroval 20 krát za sekundu, museli bychom všechno, nejen aktualizaci replikátoru, stihnout do 50 milisekund. Proto je aktuální stav nepřijatelně dlouhá doba. Úzké hrdlo najednou nebyla síť, ale příprava smysluplných dat, kterými síť zatížíme. Soustředili jsme další optimalizace právě na replikátor.
@@ -1105,61 +1174,6 @@ Testovali jsme 4 implementace, z toho 3 různé datové struktury a naivní př
% \subsection{Optimalizace QUICr}
% \subsubsection{Šifrování}
% Jednotlivé datagramy a zprávy je třeba šifrovat a pro to je třeba, aby si dvě strany vyměnili tajný klíč. Představím metodu, kterou pro výměnu budu využívat.
% \subsubsection{SPR-6}
% Metodu, kterou jsem viděl například u síťového protokolu pro hru World Of Warcraft je SRP-6. Jedná se o protokol, který nevyžaduje, aby server znal heslo klienta, ale měl u sebe pouze validátor, a klient mu díky němu dokáže, že heslo zná. Pro tento přístup je třeba udělat handshake.
\subsubsection{Congestion control}
\subsubsection{Bandwidth control}
Entity, které jsou od hráče daleko, není třeba aktualizovat tak často jako ty, které jsou k němu blízko. Již jsme nastínili, že můžeme můžeme spočítat důležitost jednotlivých entit pro klienta a omezit tak počet entit, které musí replikátor synchronizovat. Například můžeme vzdálenější entity synchronizovat méně často. Důležité je, aby se i ty dostali někdy na řadu.
\subsection{Sharding}
Proces, při kterém hráče rozdělíme do skupin, které se navzájem nevidí, i když jsou na stejném serveru blízko sebe, se říká sharding. Podobný princip funguje i v databázích.
\subsection{Horizontální škálování}
Další z metod podobná shardování, je \uv{horizontální škálování}, kdy do systému přidáváme servery, které si tak rovnoměrně rozdělí práci. V případě naší hry jsme rozdělili herní svět na zóny a o každou se stará jiný server. Takový server je \uv{zone server} a dohromady tvoří \uv{zone cluster}. Do systému jsme dále přidali \uv{cluster koordinátora}, který říká, který zone server má jakou zónu. Model mezi koordinátorem a zone serverem je klient-server. Na druhou stranu zone servery mezi sebou komunikují přímo a využívají model peer-to-peer.
Představíme, jak spolu zone servery komunikují. Využijeme k tomu už existující komponenty: replikátor a manažera zájmu. Nejprve jsme stav hry, manažera zájmu a fyzický svět do třídy \inlcpp{ZoneManager}. Tuto třídu obalíme \inlcpp{ZoneServer} třídou. Ta bude obsahovat replikátor a \inlcpp{ZoneCoordinatorClient}. Manažer zón si bude udržovat registr sousedních zón a bude se k ním chovat jako klasickým klientům. Rozdíl bude ten, že klient má jako zájem definovaný pouze bod a manažer zájmu klientovi přiřadí do zájmu entity, které jsou od bodu v dostatečné vzdálenosti. Sousedi budou mít jako zájem definovanou celou jejich plochu. Manažer zájmu má nyní na rozhraní dvě metody: \inlcpp{register\_client\_interest(interest\_id, entity)} a \inlcpp{register\_zone\_interest(interest\_id, area)}. Každý zájem je definovaný unikátním ID. O to, jaké entity pak konkrétní zájem zajímají získáme voláním \inlcpp{get_interest(interest_id)}.
Replikátor poté replikuje sousedům ty entity, které jsou od plochy souseda v dostatečné blízkosti. Pokud klient překročí do jiné zóny, měl by manažer zóny předat klienta druhé zóně. Toto modelujeme přes \inlcpp{ZoneProxy}, která reprezentuje souseda pro manažera konkrétní zóny. Implementace obsahuje \inlcpp{ZoneClusterLink}, která obsahuje QUICr endpoint, na který ostatní zóny mohou posílat cluster data.
Systémovou architekturu vidíme na obrázku \ref{fig:zone_cluster_architecture}. Vidíme, že \inlcpp{ZoneClusterLink} slouží pro komunikaci mezi servery v clusteru a zároveň pro replikaci entit, které jsou blízko hranic se sousední zónou. Když se nový server spustí, nejprve se registruje koordinátorovi. Ten mu přiřadí ID, plochu a seznam jeho sousedů včetně \inlcpp{ZoneClusterLink} adres. S každým sousedem přes QUICr naváže spojení a představí se pomocí zprávy \inlcpp{ZoneHello}. Tím si ho druhý server přidá do registru a může na něj začít přenášet klienty.
\begin{figure}
\centering
\includegraphics[width=1\textwidth]{graphics/zone_server_architecture.pdf}
\label{fig:zone_cluster_architecture}
\caption{Architektura systému s zone clusterem}
\end{figure}
\section{Výsledná hra}
V této kapitole představíme hru.
\section{Měřění}
\subsection{Závěry}
Závěr práce by se měl poskytnout jak v původním jazyce práce, tak v jazyce anglickém. Pro sazbu závěru jsou k dispozici příslušná makra. Berte na vědomí, že v anglickém závěru se aktivuje plně anglická sazba se všemi konvencemi. Tedy je třeba používat anglické uvozovky a další správné typografické prvky.
+25 -25
View File
@@ -41,31 +41,31 @@
\contentsline {subsubsection}{\numberline {4.3.2}Implementace}{31}{subsubsection.4.3.2}%
\contentsline {subsubsection}{\numberline {4.3.3}Detekce a náprava chyb}{31}{subsubsection.4.3.3}%
\contentsline {subsection}{\numberline {4.4}Serializace}{31}{subsection.4.4}%
\contentsline {subsection}{\numberline {4.5}Metriky}{32}{subsection.4.5}%
\contentsline {subsubsection}{\numberline {4.5.1}PostgreSQL}{33}{subsubsection.4.5.1}%
\contentsline {subsubsection}{\numberline {4.5.2}TimescaleDB}{33}{subsubsection.4.5.2}%
\contentsline {subsubsection}{\numberline {4.5.3}Grafana}{33}{subsubsection.4.5.3}%
\contentsline {subsubsection}{\numberline {4.5.4}Orchestrace}{34}{subsubsection.4.5.4}%
\contentsline {subsubsection}{\numberline {4.5.5}ImGui}{34}{subsubsection.4.5.5}%
\contentsline {subsubsection}{\numberline {4.5.6}Tracy}{34}{subsubsection.4.5.6}%
\contentsline {subsubsection}{\numberline {4.5.7}Konkrétní metriky}{35}{subsubsection.4.5.7}%
\contentsline {subsubsection}{\numberline {4.5.8}Sbírání v reálném čase}{35}{subsubsection.4.5.8}%
\contentsline {subsection}{\numberline {4.6}Protokol QUICr}{35}{subsection.4.6}%
\contentsline {subsubsection}{\numberline {4.6.1}Rámec}{36}{subsubsection.4.6.1}%
\contentsline {subsubsection}{\numberline {4.6.2}Handshake}{36}{subsubsection.4.6.2}%
\contentsline {subsubsection}{\numberline {4.6.3}Spolehlivost}{38}{subsubsection.4.6.3}%
\contentsline {subsubsection}{\numberline {4.6.4}Enkodér}{38}{subsubsection.4.6.4}%
\contentsline {subsubsection}{\numberline {4.6.5}Testování}{39}{subsubsection.4.6.5}%
\contentsline {subsubsection}{\numberline {4.6.6}Měření}{39}{subsubsection.4.6.6}%
\contentsline {subsection}{\numberline {4.7}Optimalizace replikátoru}{41}{subsection.4.7}%
\contentsline {subsection}{\numberline {4.8}Optimalizace manažera zájmů}{43}{subsection.4.8}%
\contentsline {subsubsection}{\numberline {4.8.1}Congestion control}{44}{subsubsection.4.8.1}%
\contentsline {subsubsection}{\numberline {4.8.2}Bandwidth control}{44}{subsubsection.4.8.2}%
\contentsline {subsection}{\numberline {4.9}Sharding}{44}{subsection.4.9}%
\contentsline {subsection}{\numberline {4.10}Horizontální škálování}{44}{subsection.4.10}%
\contentsline {section}{\numberline {5}Výsledná hra}{45}{section.5}%
\contentsline {section}{\numberline {6}Měřění}{45}{section.6}%
\contentsline {subsection}{\numberline {6.1}Závěry}{45}{subsection.6.1}%
\contentsline {subsection}{\numberline {4.5}Protokol QUICr}{32}{subsection.4.5}%
\contentsline {subsubsection}{\numberline {4.5.1}Rámce}{33}{subsubsection.4.5.1}%
\contentsline {subsubsection}{\numberline {4.5.2}Handshake}{33}{subsubsection.4.5.2}%
\contentsline {subsubsection}{\numberline {4.5.3}Spolehlivost}{34}{subsubsection.4.5.3}%
\contentsline {subsubsection}{\numberline {4.5.4}Enkodér}{35}{subsubsection.4.5.4}%
\contentsline {subsubsection}{\numberline {4.5.5}Testování}{36}{subsubsection.4.5.5}%
\contentsline {subsubsection}{\numberline {4.5.6}Congestion control}{36}{subsubsection.4.5.6}%
\contentsline {subsubsection}{\numberline {4.5.7}Bandwidth control}{36}{subsubsection.4.5.7}%
\contentsline {subsection}{\numberline {4.6}Sharding}{36}{subsection.4.6}%
\contentsline {subsection}{\numberline {4.7}Horizontální škálování}{36}{subsection.4.7}%
\contentsline {section}{\numberline {5}Výsledná hra}{37}{section.5}%
\contentsline {section}{\numberline {6}Měřění}{38}{section.6}%
\contentsline {subsection}{\numberline {6.1}Metriky}{38}{subsection.6.1}%
\contentsline {subsubsection}{\numberline {6.1.1}PostgreSQL}{38}{subsubsection.6.1.1}%
\contentsline {subsubsection}{\numberline {6.1.2}TimescaleDB}{38}{subsubsection.6.1.2}%
\contentsline {subsubsection}{\numberline {6.1.3}Grafana}{38}{subsubsection.6.1.3}%
\contentsline {subsubsection}{\numberline {6.1.4}Orchestrace}{39}{subsubsection.6.1.4}%
\contentsline {subsubsection}{\numberline {6.1.5}ImGui}{39}{subsubsection.6.1.5}%
\contentsline {subsubsection}{\numberline {6.1.6}Tracy}{39}{subsubsection.6.1.6}%
\contentsline {subsubsection}{\numberline {6.1.7}Konkrétní metriky}{40}{subsubsection.6.1.7}%
\contentsline {subsubsection}{\numberline {6.1.8}Sbírání v reálném čase}{40}{subsubsection.6.1.8}%
\contentsline {subsection}{\numberline {6.2}QUICr}{41}{subsection.6.2}%
\contentsline {subsection}{\numberline {6.3}Optimalizace replikátoru}{43}{subsection.6.3}%
\contentsline {subsection}{\numberline {6.4}Optimalizace manažera zájmů}{45}{subsection.6.4}%
\contentsline {subsection}{\numberline {6.5}Závěry}{46}{subsection.6.5}%
\contentsline {section}{Z\'av\v er}{47}{section*.3}%
\babel@toc {czech}{}\relax
\babel@toc {czech}{}\relax