From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=0.1 required=5.0 tests=BAYES_00,FREEMAIL_FROM, PDS_OTHER_BAD_TLD autolearn=no autolearn_force=no version=3.4.4 X-Received: by 10.157.13.19 with SMTP id 19mr15872361oti.4.1496918160848; Thu, 08 Jun 2017 03:36:00 -0700 (PDT) X-Received: by 10.157.80.151 with SMTP id b23mr853947oth.5.1496918160811; Thu, 08 Jun 2017 03:36:00 -0700 (PDT) Path: eternal-september.org!reader01.eternal-september.org!reader02.eternal-september.org!news.eternal-september.org!news.eternal-september.org!feeder.eternal-september.org!news.glorb.com!67no368433itx.0!news-out.google.com!k7ni1623itk.0!nntp.google.com!67no369622itx.0!postnews.google.com!glegroupsg2000goo.googlegroups.com!not-for-mail Newsgroups: comp.lang.ada Date: Thu, 8 Jun 2017 03:36:00 -0700 (PDT) Complaints-To: groups-abuse@google.com Injection-Info: glegroupsg2000goo.googlegroups.com; posting-host=92.103.99.138; posting-account=GmLOCAoAAABtDjDYQ4FbF8OEbF1VMKeh NNTP-Posting-Host: 92.103.99.138 User-Agent: G2/1.0 MIME-Version: 1.0 Message-ID: Subject: GNAT.Sockets Streaming inefficiency From: masterglob@gmail.com Injection-Date: Thu, 08 Jun 2017 10:36:00 +0000 Content-Type: text/plain; charset="UTF-8" Xref: news.eternal-september.org comp.lang.ada:46924 Date: 2017-06-08T03:36:00-07:00 List-Id: 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;