From: masterglob@gmail.com
Subject: GNAT.Sockets Streaming inefficiency
Date: Thu, 8 Jun 2017 03:36:00 -0700 (PDT)
Date: 2017-06-08T03:36:00-07:00 [thread overview]
Message-ID: <c00a464f-5587-4a8e-a11a-589f7030127a@googlegroups.com> (raw)
Configuration: X64, Linux & Windows (GNATPRO 7.4.2)
While using GNAT.Sockets.Stream_Access, there is a real performance issue while using String'Output(...).
My test sends 500 times a 1024-long String using String'Output(TCP_Stream on 127.0.0.1) and the result is:
- Linux : average 'output duration = 3 us
- Windows: average 'output duration = 250 us
From prior discussion with AdaCore, the "String" type is the only one for which this latency is NOT observed on Linux.
Any idea on:
- is there a way to get similar performance on Windows (maybe using another type or method?)
- is there any configuration that may solve this issue?
=============
Result on W7/64
---------
OS=Windows_NT cygwin
GNAT Pro 7.4.2 (20160527-49)
[SERVER] start...
[SERVER]:bind... 127.0.0.1:4264
[CLIENT] connected...
[SERVER]:connection from 127.0.0.1:56008
[SERVER] Sending 500 messages ...
[CLIENT] waiting for 500 messages ...
[CLIENT]:execution time: 0.000000000
[Server] execution time ( 500msg): 0.140400900 s
[Server] Output_Exec time (1 msg): 0.280801800 ms
[Server] Output_Duration time (1 msg): 0.263417164 ms
=============
Result on Ubuntu/64
---------
OS=
GNAT Pro 7.4.2 (20160527-49)
[SERVER] start...
[SERVER]:bind... 127.0.0.1:4264
[SERVER]:connection from 127.0.0.1:52574
[CLIENT] connected...
[SERVER] Sending 500 messages ...
[CLIENT] waiting for 500 messages ...
[Server] execution time ( 500msg): 0.001783393 s
[Server] Output_Exec time (1 msg): 0.003072174 ms
[Server] Output_Duration time (1 msg): 0.003204778 ms
[CLIENT]:execution time: 0.001561405
=============
Makefile:
---------
all:build exec
build:
@gprbuild -p -Ptest_stream_socket_string.gpr
exec:
@echo "OS=$$OS $$OSTYPE"
@echo $$(gnat --version|head -1)
@obj/test_stream_socket_string
=============
test_stream_socket_string.gpr:
---------
project Test_Stream_Socket_String is
for Object_Dir use "obj";
for Exec_Dir use "obj";
for Main use ("test_stream_socket_string.adb");
for Source_Dirs use (".");
for Languages use ("Ada");
package Builder is
for Default_Switches ("Ada") use ("-g","-s","-j0");
end Builder;
package Compiler is
Ada_Opt := ("-O0");
Ada_Comp := ("-gnat12","-g","-gnatU","-gnato","-gnatVa","-fstack-check","-fstack-usage","-gnateE","-gnateF");
Ada_Style := ("-gnaty3aAbBCdefhiklL15M120nOprStux");
Ada_Warning := ("-gnatwah.h.o.st.w");
for Default_Switches ("Ada") use Ada_Opt & Ada_Comp & Ada_Warning & Ada_Style;
end Compiler;
package Binder is
for Default_Switches ("Ada") use ("-v","-E","-R","-T0");
end Binder;
package Linker is
for Default_Switches ("Ada") use ("-g","-v") ;
end Linker;
end Test_Stream_Socket_String;
=============
test_stream_socket_string.adb
---------
with Ada.Execution_Time,
Ada.Real_Time,
Ada.Text_IO,
Ada.Exceptions,
GNAT.Sockets,
GNAT.Traceback.Symbolic,
GNAT.OS_Lib;
use GNAT,
Ada;
use type GNAT.Sockets.Selector_Status,
Ada.Real_Time.Time,
Ada.Execution_Time.CPU_Time;
procedure Test_Stream_Socket_String is
Port : constant Sockets.Port_Type := 4264;
Ip_Addr : constant String := "127.0.0.1";
task type Client_Thread_T is
entry Start;
entry Synch;
entry Wait;
end Client_Thread_T;
Client_Thread : Client_Thread_T;
task type Server_Thread_T is
entry Start;
entry Wait;
end Server_Thread_T;
Server_Thread : Server_Thread_T;
task body Client_Thread_T is
task body Server_Thread_T is
Nb_Loop : constant := 500;
Cpt : Integer := Nb_Loop;
Msg_Size : constant := 1024; -- 1 Ko
Exec_Start_Time : Execution_Time.CPU_Time;
Exec_Output1 : Execution_Time.CPU_Time;
Exec_Output2 : Real_Time.Time;
Output_Exec : Duration := 0.0;
Output_Duration : Duration := 0.0;
Listen : Sockets.Socket_Type;
Client : Sockets.Socket_Type;
Address : Sockets.Sock_Addr_Type := (Family => Sockets.Family_Inet,
Addr => Sockets.Inet_Addr (Ip_Addr),
Port => Port);
Channel : Sockets.Stream_Access;
begin
accept Start;
Text_IO.Put_Line ("[SERVER] start...");
Sockets.Create_Socket (Socket => Listen);
Text_IO.Put_Line ("[SERVER]:bind... " & Sockets.Image (Address));
Sockets.Bind_Socket (Socket => Listen,
Address => Address);
Sockets.Listen_Socket (Listen);
Sockets.Accept_Socket (Listen, Client, Address);
Text_IO.Put_Line ("[SERVER]:connection from " & Sockets.Image (Sockets.Get_Peer_Name (Client)));
Channel := Sockets.Stream (Socket => Client);
Exec_Start_Time := Execution_Time.Clock;
Integer'Output (Channel, Cpt);
Text_IO.Put_Line ("[SERVER] Sending" & Cpt'Img & " messages ...");
while Cpt > 0 loop
-- Text_IO.Put ('+');
declare
S : constant String (1 .. Msg_Size) := (others => '?');
begin
Exec_Output1 := Execution_Time.Clock;
Exec_Output2 := Real_Time.Clock;
String'Output (Channel, S);
Output_Exec := Output_Exec +
Real_Time.To_Duration (Execution_Time.Clock - Exec_Output1);
Output_Duration := Output_Duration +
Real_Time.To_Duration (Real_Time.Clock - Exec_Output2);
end;
Cpt := Cpt - 1;
end loop;
Text_IO.Put_Line ("[Server] execution time (" & Nb_Loop'Img & "msg): " &
Real_Time.To_Duration (Execution_Time.Clock - Exec_Start_Time)'Img & " s");
Text_IO.Put_Line ("[Server] Output_Exec time (1 msg): " &
Duration'Image (1000.0 * Output_Exec / (Nb_Loop - Cpt)) & " ms");
Text_IO.Put_Line ("[Server] Output_Duration time (1 msg): " &
Duration'Image (1000.0 * Output_Duration / (Nb_Loop - Cpt)) & " ms");
Sockets.Close_Socket (Socket => Listen);
accept Wait;
-- Text_IO.New_Line;
exception
when E : others =>
Text_IO.New_Line;
Text_IO.Put_Line ("[Server] Exception: " & Exceptions.Exception_Information (E));
Text_IO.Put_Line (Exceptions.Exception_Message (E));
Text_IO.Put_Line (Traceback.Symbolic.Symbolic_Traceback (E));
if Cpt /= Nb_Loop then
Text_IO.Put_Line ("[Server] Output_Duration time: " &
Duration'Image (1000.0 * Output_Duration / (Nb_Loop - Cpt)) & " ms");
end if;
GNAT.OS_Lib.OS_Abort;
end Server_Thread_T;
begin
Server_Thread.Start;
Client_Thread.Start;
Client_Thread.Synch;
Server_Thread.Wait;
Client_Thread.Wait;
-- Text_IO.New_Line;
exception
when E : others =>
Text_IO.Put_Line (Exceptions.Exception_Information (E));
Text_IO.Put_Line (Exceptions.Exception_Message (E));
Text_IO.Put_Line (Traceback.Symbolic.Symbolic_Traceback (E));
end Test_Stream_Socket_String;
next reply other threads:[~2017-06-08 10:36 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-06-08 10:36 masterglob [this message]
2017-06-08 14:46 ` GNAT.Sockets Streaming inefficiency Dmitry A. Kazakov
2017-06-08 15:39 ` Robert Eachus
2017-06-09 13:30 ` gautier_niouzes
2017-06-09 15:24 ` Dmitry A. Kazakov
2017-06-19 9:22 ` masterglob
replies disabled
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox