[Lldb-commits] [lldb] r237953 - Added a new command in ProcessGDBRemote that can figure out the performance characterisitics of your GDB remote server.

Greg Clayton gclayton at apple.com
Thu May 21 13:52:07 PDT 2015


Author: gclayton
Date: Thu May 21 15:52:06 2015
New Revision: 237953

URL: http://llvm.org/viewvc/llvm-project?rev=237953&view=rev
Log:
Added a new command in ProcessGDBRemote that can figure out the performance characterisitics of your GDB remote server. 

To addess this, attach to any GDB server and when stopped type:

(lldb) process plugin packet speed-test

The default will send a variety of packets with different amounts of data to send/receive and print the performance of each packet type:

Testing sending 1000 packets of various sizes:
qSpeedTest(send=0      , recv=0      ) in 0.057837000 sec for  17289.97 packets/sec (  0.057837 ms per packet) with standard deviation of   0.007705 ms
qSpeedTest(send=0      , recv=4      ) in 0.056162000 sec for  17805.63 packets/sec (  0.056162 ms per packet) with standard deviation of   0.004439 ms
qSpeedTest(send=0      , recv=8      ) in 0.057687000 sec for  17334.93 packets/sec (  0.057687 ms per packet) with standard deviation of   0.008135 ms
qSpeedTest(send=0      , recv=16     ) in 0.058547000 sec for  17080.29 packets/sec (  0.058547 ms per packet) with standard deviation of   0.005884 ms
qSpeedTest(send=0      , recv=32     ) in 0.058289000 sec for  17155.89 packets/sec (  0.058289 ms per packet) with standard deviation of   0.004057 ms
qSpeedTest(send=0      , recv=64     ) in 0.061324000 sec for  16306.83 packets/sec (  0.061324 ms per packet) with standard deviation of   0.010838 ms
qSpeedTest(send=0      , recv=128    ) in 0.065688000 sec for  15223.48 packets/sec (  0.065688 ms per packet) with standard deviation of   0.006997 ms
qSpeedTest(send=0      , recv=256    ) in 0.070621000 sec for  14160.09 packets/sec (  0.070621 ms per packet) with standard deviation of   0.006188 ms
qSpeedTest(send=0      , recv=512    ) in 0.086738000 sec for  11528.97 packets/sec (  0.086738 ms per packet) with standard deviation of   0.007867 ms
qSpeedTest(send=0      , recv=1024   ) in 0.146375000 sec for   6831.77 packets/sec (  0.146375 ms per packet) with standard deviation of   0.010313 ms
qSpeedTest(send=4      , recv=0      ) in 0.057807000 sec for  17298.94 packets/sec (  0.057807 ms per packet) with standard deviation of   0.009702 ms
....

It will then also use various sizes to receive 4MB of data from the GDB server and print out the stats:

Testing receiving 4.0MB of data using varying receive packet sizes:
qSpeedTest(send=0      , recv=32     ) 131072 packets needed to receive 4.0MB in 7.721290000 sec for 0.518048 MB/sec for  16975.40 packets/sec (  0.058909 ms per packet)
qSpeedTest(send=0      , recv=64     )  65536 packets needed to receive 4.0MB in 4.029236000 sec for 0.992744 MB/sec for  16265.12 packets/sec (  0.061481 ms per packet)
qSpeedTest(send=0      , recv=128    )  32768 packets needed to receive 4.0MB in 2.233854000 sec for 1.790627 MB/sec for  14668.82 packets/sec (  0.068172 ms per packet)
qSpeedTest(send=0      , recv=256    )  16384 packets needed to receive 4.0MB in 1.160024000 sec for 3.448204 MB/sec for  14123.84 packets/sec (  0.070802 ms per packet)
qSpeedTest(send=0      , recv=512    )   8192 packets needed to receive 4.0MB in 0.701603000 sec for 5.701230 MB/sec for  11676.12 packets/sec (  0.085645 ms per packet)
qSpeedTest(send=0      , recv=1024   )   4096 packets needed to receive 4.0MB in 0.596786000 sec for 6.702570 MB/sec for   6863.43 packets/sec (  0.145700 ms per packet)

There is a JSON mode so we can use this in the test suite to track GDB server performance for each platform:

(lldb) process plugin packet speed-test --json
{ "packet_speeds" : {
    "num_packets" : 1000,
    "results" : [
     {"send_size" :      0, "recv_size" :      0, "total_time_nsec" :     64516000, "standard_deviation_nsec" :     20566 },
     {"send_size" :      0, "recv_size" :      4, "total_time_nsec" :     59648000, "standard_deviation_nsec" :     10493 },
     {"send_size" :      0, "recv_size" :      8, "total_time_nsec" :     56894000, "standard_deviation_nsec" :      5480 },
     {"send_size" :      0, "recv_size" :     16, "total_time_nsec" :     59422000, "standard_deviation_nsec" :      6557 },
     {"send_size" :      0, "recv_size" :     32, "total_time_nsec" :     61159000, "standard_deviation_nsec" :     12384 },
     {"send_size" :      0, "recv_size" :     64, "total_time_nsec" :     61386000, "standard_deviation_nsec" :      9208 },
     {"send_size" :      0, "recv_size" :    128, "total_time_nsec" :     64768000, "standard_deviation_nsec" :      4737 },
     {"send_size" :      0, "recv_size" :    256, "total_time_nsec" :     71046000, "standard_deviation_nsec" :      5904 },
     {"send_size" :      0, "recv_size" :    512, "total_time_nsec" :     87233000, "standard_deviation_nsec" :      8967 },
     {"send_size" :      0, "recv_size" :   1024, "total_time_nsec" :    146629000, "standard_deviation_nsec" :      9526 },
     {"send_size" :      4, "recv_size" :      0, "total_time_nsec" :     57131000, "standard_deviation_nsec" :      7884 },
     {"send_size" :      4, "recv_size" :      4, "total_time_nsec" :     56772000, "standard_deviation_nsec" :      6064 },
     {"send_size" :      4, "recv_size" :      8, "total_time_nsec" :     57450000, "standard_deviation_nsec" :      6341 },
     {"send_size" :      4, "recv_size" :     16, "total_time_nsec" :     58279000, "standard_deviation_nsec" :      5998 },
     {"send_size" :      4, "recv_size" :     32, "total_time_nsec" :     59995000, "standard_deviation_nsec" :      6294 },
     {"send_size" :      4, "recv_size" :     64, "total_time_nsec" :     61632000, "standard_deviation_nsec" :      7838 },
     {"send_size" :      4, "recv_size" :    128, "total_time_nsec" :     66535000, "standard_deviation_nsec" :      8026 },
     {"send_size" :      4, "recv_size" :    256, "total_time_nsec" :     72754000, "standard_deviation_nsec" :      9519 },
     {"send_size" :      4, "recv_size" :    512, "total_time_nsec" :     87072000, "standard_deviation_nsec" :      9268 },
     {"send_size" :      4, "recv_size" :   1024, "total_time_nsec" :    147221000, "standard_deviation_nsec" :      9702 },
     {"send_size" :      8, "recv_size" :      0, "total_time_nsec" :     57900000, "standard_deviation_nsec" :      7356 },
     {"send_size" :      8, "recv_size" :      4, "total_time_nsec" :     58116000, "standard_deviation_nsec" :      7630 },
     {"send_size" :      8, "recv_size" :      8, "total_time_nsec" :     57745000, "standard_deviation_nsec" :      8541 },
     {"send_size" :      8, "recv_size" :     16, "total_time_nsec" :     59091000, "standard_deviation_nsec" :      7851 },
     {"send_size" :      8, "recv_size" :     32, "total_time_nsec" :     59943000, "standard_deviation_nsec" :      6761 },
     {"send_size" :      8, "recv_size" :     64, "total_time_nsec" :     62097000, "standard_deviation_nsec" :      8580 },
     {"send_size" :      8, "recv_size" :    128, "total_time_nsec" :     69942000, "standard_deviation_nsec" :     16645 },
     {"send_size" :      8, "recv_size" :    256, "total_time_nsec" :     72927000, "standard_deviation_nsec" :     11031 },
     {"send_size" :      8, "recv_size" :    512, "total_time_nsec" :     87221000, "standard_deviation_nsec" :      8002 },
     {"send_size" :      8, "recv_size" :   1024, "total_time_nsec" :    148696000, "standard_deviation_nsec" :     10383 },
     {"send_size" :     16, "recv_size" :      0, "total_time_nsec" :     59890000, "standard_deviation_nsec" :     15160 },
     {"send_size" :     16, "recv_size" :      4, "total_time_nsec" :     56664000, "standard_deviation_nsec" :      4650 },
     {"send_size" :     16, "recv_size" :      8, "total_time_nsec" :     57574000, "standard_deviation_nsec" :      7787 },
     {"send_size" :     16, "recv_size" :     16, "total_time_nsec" :     59312000, "standard_deviation_nsec" :      8104 },
     {"send_size" :     16, "recv_size" :     32, "total_time_nsec" :     59764000, "standard_deviation_nsec" :      7496 },
     {"send_size" :     16, "recv_size" :     64, "total_time_nsec" :     61644000, "standard_deviation_nsec" :      8331 },
     {"send_size" :     16, "recv_size" :    128, "total_time_nsec" :     66476000, "standard_deviation_nsec" :      9251 },
     {"send_size" :     16, "recv_size" :    256, "total_time_nsec" :     72386000, "standard_deviation_nsec" :      8627 },
     {"send_size" :     16, "recv_size" :    512, "total_time_nsec" :     87810000, "standard_deviation_nsec" :     12318 },
     {"send_size" :     16, "recv_size" :   1024, "total_time_nsec" :    146918000, "standard_deviation_nsec" :     11595 },
     {"send_size" :     32, "recv_size" :      0, "total_time_nsec" :     56493000, "standard_deviation_nsec" :      6577 },
     {"send_size" :     32, "recv_size" :      4, "total_time_nsec" :     57069000, "standard_deviation_nsec" :      5931 },
     {"send_size" :     32, "recv_size" :      8, "total_time_nsec" :     57563000, "standard_deviation_nsec" :      8157 },
     {"send_size" :     32, "recv_size" :     16, "total_time_nsec" :     59694000, "standard_deviation_nsec" :      6932 },
     {"send_size" :     32, "recv_size" :     32, "total_time_nsec" :     60852000, "standard_deviation_nsec" :      8010 },
     {"send_size" :     32, "recv_size" :     64, "total_time_nsec" :     61926000, "standard_deviation_nsec" :      8372 },
     {"send_size" :     32, "recv_size" :    128, "total_time_nsec" :     66734000, "standard_deviation_nsec" :      8047 },
     {"send_size" :     32, "recv_size" :    256, "total_time_nsec" :     72000000, "standard_deviation_nsec" :      8103 },
     {"send_size" :     32, "recv_size" :    512, "total_time_nsec" :     88268000, "standard_deviation_nsec" :     12289 },
     {"send_size" :     32, "recv_size" :   1024, "total_time_nsec" :    147946000, "standard_deviation_nsec" :     12122 },
     {"send_size" :     64, "recv_size" :      0, "total_time_nsec" :     58126000, "standard_deviation_nsec" :      5895 },
     {"send_size" :     64, "recv_size" :      4, "total_time_nsec" :     58927000, "standard_deviation_nsec" :      8933 },
     {"send_size" :     64, "recv_size" :      8, "total_time_nsec" :     58163000, "standard_deviation_nsec" :      6663 },
     {"send_size" :     64, "recv_size" :     16, "total_time_nsec" :     59901000, "standard_deviation_nsec" :      8340 },
     {"send_size" :     64, "recv_size" :     32, "total_time_nsec" :     60365000, "standard_deviation_nsec" :      6319 },
     {"send_size" :     64, "recv_size" :     64, "total_time_nsec" :     61776000, "standard_deviation_nsec" :      7461 },
     {"send_size" :     64, "recv_size" :    128, "total_time_nsec" :     66984000, "standard_deviation_nsec" :      6810 },
     {"send_size" :     64, "recv_size" :    256, "total_time_nsec" :     73913000, "standard_deviation_nsec" :      8826 },
     {"send_size" :     64, "recv_size" :    512, "total_time_nsec" :     88134000, "standard_deviation_nsec" :      8356 },
     {"send_size" :     64, "recv_size" :   1024, "total_time_nsec" :    146932000, "standard_deviation_nsec" :      7571 },
     {"send_size" :    128, "recv_size" :      0, "total_time_nsec" :     57616000, "standard_deviation_nsec" :      6158 },
     {"send_size" :    128, "recv_size" :      4, "total_time_nsec" :     59091000, "standard_deviation_nsec" :      7458 },
     {"send_size" :    128, "recv_size" :      8, "total_time_nsec" :     60263000, "standard_deviation_nsec" :     11999 },
     {"send_size" :    128, "recv_size" :     16, "total_time_nsec" :     59238000, "standard_deviation_nsec" :      6102 },
     {"send_size" :    128, "recv_size" :     32, "total_time_nsec" :     60783000, "standard_deviation_nsec" :      6244 },
     {"send_size" :    128, "recv_size" :     64, "total_time_nsec" :     62975000, "standard_deviation_nsec" :      8947 },
     {"send_size" :    128, "recv_size" :    128, "total_time_nsec" :     65742000, "standard_deviation_nsec" :      5907 },
     {"send_size" :    128, "recv_size" :    256, "total_time_nsec" :     72402000, "standard_deviation_nsec" :      6601 },
     {"send_size" :    128, "recv_size" :    512, "total_time_nsec" :     87457000, "standard_deviation_nsec" :      9004 },
     {"send_size" :    128, "recv_size" :   1024, "total_time_nsec" :    148412000, "standard_deviation_nsec" :     10532 },
     {"send_size" :    256, "recv_size" :      0, "total_time_nsec" :     58705000, "standard_deviation_nsec" :      7274 },
     {"send_size" :    256, "recv_size" :      4, "total_time_nsec" :     58818000, "standard_deviation_nsec" :      5453 },
     {"send_size" :    256, "recv_size" :      8, "total_time_nsec" :     59451000, "standard_deviation_nsec" :      6926 },
     {"send_size" :    256, "recv_size" :     16, "total_time_nsec" :     60237000, "standard_deviation_nsec" :      5781 },
     {"send_size" :    256, "recv_size" :     32, "total_time_nsec" :     61456000, "standard_deviation_nsec" :      5591 },
     {"send_size" :    256, "recv_size" :     64, "total_time_nsec" :     62615000, "standard_deviation_nsec" :      7588 },
     {"send_size" :    256, "recv_size" :    128, "total_time_nsec" :     68554000, "standard_deviation_nsec" :      7766 },
     {"send_size" :    256, "recv_size" :    256, "total_time_nsec" :     74557000, "standard_deviation_nsec" :      8748 },
     {"send_size" :    256, "recv_size" :    512, "total_time_nsec" :     87929000, "standard_deviation_nsec" :      9510 },
     {"send_size" :    256, "recv_size" :   1024, "total_time_nsec" :    148522000, "standard_deviation_nsec" :     11394 },
     {"send_size" :    512, "recv_size" :      0, "total_time_nsec" :     59697000, "standard_deviation_nsec" :      7825 },
     {"send_size" :    512, "recv_size" :      4, "total_time_nsec" :     59427000, "standard_deviation_nsec" :      5706 },
     {"send_size" :    512, "recv_size" :      8, "total_time_nsec" :     59538000, "standard_deviation_nsec" :      6863 },
     {"send_size" :    512, "recv_size" :     16, "total_time_nsec" :     61139000, "standard_deviation_nsec" :      7645 },
     {"send_size" :    512, "recv_size" :     32, "total_time_nsec" :     62203000, "standard_deviation_nsec" :      7985 },
     {"send_size" :    512, "recv_size" :     64, "total_time_nsec" :     62577000, "standard_deviation_nsec" :      8118 },
     {"send_size" :    512, "recv_size" :    128, "total_time_nsec" :     68722000, "standard_deviation_nsec" :     10581 },
     {"send_size" :    512, "recv_size" :    256, "total_time_nsec" :     74290000, "standard_deviation_nsec" :      8931 },
     {"send_size" :    512, "recv_size" :    512, "total_time_nsec" :     88635000, "standard_deviation_nsec" :      7771 },
     {"send_size" :    512, "recv_size" :   1024, "total_time_nsec" :    149589000, "standard_deviation_nsec" :     11456 },
     {"send_size" :   1024, "recv_size" :      0, "total_time_nsec" :     63243000, "standard_deviation_nsec" :      6331 },
     {"send_size" :   1024, "recv_size" :      4, "total_time_nsec" :     64381000, "standard_deviation_nsec" :      8372 },
     {"send_size" :   1024, "recv_size" :      8, "total_time_nsec" :     63481000, "standard_deviation_nsec" :      5608 },
     {"send_size" :   1024, "recv_size" :     16, "total_time_nsec" :     65549000, "standard_deviation_nsec" :      8826 },
     {"send_size" :   1024, "recv_size" :     32, "total_time_nsec" :     65485000, "standard_deviation_nsec" :      6822 },
     {"send_size" :   1024, "recv_size" :     64, "total_time_nsec" :     67125000, "standard_deviation_nsec" :      9829 },
     {"send_size" :   1024, "recv_size" :    128, "total_time_nsec" :     72680000, "standard_deviation_nsec" :      7641 },
     {"send_size" :   1024, "recv_size" :    256, "total_time_nsec" :     79206000, "standard_deviation_nsec" :      9854 },
     {"send_size" :   1024, "recv_size" :    512, "total_time_nsec" :     92418000, "standard_deviation_nsec" :      9107 },
     {"send_size" :   1024, "recv_size" :   1024, "total_time_nsec" :    152392000, "standard_deviation_nsec" :     11124 }
    ]
  },
  "download_speed" : {
    "byte_size" : 4194304,
    "results" : [
     {"send_size" :      0, "recv_size" :     32, "total_time_nsec" :   7735630000 },
     {"send_size" :      0, "recv_size" :     64, "total_time_nsec" :   3985169000 },
     {"send_size" :      0, "recv_size" :    128, "total_time_nsec" :   2128791000 },
     {"send_size" :      0, "recv_size" :    256, "total_time_nsec" :   1172077000 },
     {"send_size" :      0, "recv_size" :    512, "total_time_nsec" :    703833000 },
     {"send_size" :      0, "recv_size" :   1024, "total_time_nsec" :    594966000 }
    ]
  }
}





Modified:
    lldb/trunk/include/lldb/Core/IOHandler.h
    lldb/trunk/source/Core/IOHandler.cpp
    lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
    lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
    lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp

Modified: lldb/trunk/include/lldb/Core/IOHandler.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/IOHandler.h?rev=237953&r1=237952&r2=237953&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/IOHandler.h (original)
+++ lldb/trunk/include/lldb/Core/IOHandler.h Thu May 21 15:52:06 2015
@@ -626,6 +626,7 @@ namespace lldb_private {
         bool m_multi_line;
         bool m_color_prompts;
         bool m_interrupt_exits;
+        bool m_editing; // Set to true when fetching a line manually (not using libedit)
     };
     
     // The order of base classes is important. Look at the constructor of IOHandlerConfirm

Modified: lldb/trunk/source/Core/IOHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/IOHandler.cpp?rev=237953&r1=237952&r2=237953&view=diff
==============================================================================
--- lldb/trunk/source/Core/IOHandler.cpp (original)
+++ lldb/trunk/source/Core/IOHandler.cpp Thu May 21 15:52:06 2015
@@ -380,7 +380,8 @@ IOHandlerEditline::IOHandlerEditline (De
     m_curr_line_idx (UINT32_MAX),
     m_multi_line (multi_line),
     m_color_prompts (color_prompts),
-    m_interrupt_exits (true)
+    m_interrupt_exits (true),
+    m_editing (false)
 {
     SetPrompt(prompt);
 
@@ -474,6 +475,7 @@ IOHandlerEditline::GetLine (std::string
             char buffer[256];
             bool done = false;
             bool got_line = false;
+            m_editing = true;
             while (!done)
             {
                 if (fgets(buffer, sizeof(buffer), in) == NULL)
@@ -508,6 +510,7 @@ IOHandlerEditline::GetLine (std::string
                     line.append(buffer, buffer_len);
                 }
             }
+            m_editing = false;
             // We might have gotten a newline on a line by itself
             // make sure to return true in this case.
             return got_line;
@@ -754,7 +757,7 @@ IOHandlerEditline::Refresh ()
     {
         m_editline_ap->Refresh();
     }
-    else
+    else if (m_editing)
     {
 #endif
         const char *prompt = GetPrompt();

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp?rev=237953&r1=237952&r2=237953&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp Thu May 21 15:52:06 2015
@@ -11,10 +11,12 @@
 #include "GDBRemoteCommunicationClient.h"
 
 // C Includes
+#include <math.h>
 #include <sys/stat.h>
 
 // C++ Includes
 #include <sstream>
+#include <numeric>
 
 // Other libraries and framework includes
 #include "llvm/ADT/STLExtras.h"
@@ -154,11 +156,6 @@ GDBRemoteCommunicationClient::HandshakeW
         // a live connection to a remote GDB server...
         if (QueryNoAckModeSupported())
         {
-#if 0
-            // Set above line to "#if 1" to test packet speed if remote GDB server
-            // supports the qSpeedTest packet...
-            TestPacketSpeed(10000);
-#endif
             return true;
         }
         else
@@ -2797,87 +2794,165 @@ GDBRemoteCommunicationClient::SetNonStop
 
 }
 
+static void
+MakeSpeedTestPacket(StreamString &packet, uint32_t send_size, uint32_t recv_size)
+{
+    packet.Clear();
+    packet.Printf ("qSpeedTest:response_size:%i;data:", recv_size);
+    uint32_t bytes_left = send_size;
+    while (bytes_left > 0)
+    {
+        if (bytes_left >= 26)
+        {
+            packet.PutCString("abcdefghijklmnopqrstuvwxyz");
+            bytes_left -= 26;
+        }
+        else
+        {
+            packet.Printf ("%*.*s;", bytes_left, bytes_left, "abcdefghijklmnopqrstuvwxyz");
+            bytes_left = 0;
+        }
+    }
+}
+
+template<typename T>
+T calculate_standard_deviation(const std::vector<T> &v)
+{
+    T sum = std::accumulate(std::begin(v), std::end(v), T(0));
+    T mean =  sum / (T)v.size();
+    T accum = T(0);
+    std::for_each (std::begin(v), std::end(v), [&](const T d) {
+        T delta = d - mean;
+        accum += delta * delta;
+    });
+
+    T stdev = sqrt(accum / (v.size()-1));
+    return stdev;
+}
+
 void
-GDBRemoteCommunicationClient::TestPacketSpeed (const uint32_t num_packets)
+GDBRemoteCommunicationClient::TestPacketSpeed (const uint32_t num_packets, uint32_t max_send, uint32_t max_recv, bool json, Stream &strm)
 {
     uint32_t i;
     TimeValue start_time, end_time;
     uint64_t total_time_nsec;
     if (SendSpeedTestPacket (0, 0))
     {
-        static uint32_t g_send_sizes[] = { 0, 64, 128, 512, 1024 };
-        static uint32_t g_recv_sizes[] = { 0, 64, 128, 512, 1024 }; //, 4*1024, 8*1024, 16*1024, 32*1024, 48*1024, 64*1024, 96*1024, 128*1024 };
-        const size_t k_num_send_sizes = llvm::array_lengthof(g_send_sizes);
-        const size_t k_num_recv_sizes = llvm::array_lengthof(g_recv_sizes);
-        const uint64_t k_recv_amount = 4*1024*1024; // Receive 4MB
-        for (uint32_t send_idx = 0; send_idx < k_num_send_sizes; ++send_idx)
-        {
-            const uint32_t send_size = g_send_sizes[send_idx];
-            for (uint32_t recv_idx = 0; recv_idx < k_num_recv_sizes; ++recv_idx)
-            {
-                const uint32_t recv_size = g_recv_sizes[recv_idx];
-                StreamString packet;
-                packet.Printf ("qSpeedTest:response_size:%i;data:", recv_size);
-                uint32_t bytes_left = send_size;
-                while (bytes_left > 0)
+        StreamString packet;
+        if (json)
+            strm.Printf("{ \"packet_speeds\" : {\n    \"num_packets\" : %u,\n    \"results\" : [", num_packets);
+        else
+            strm.Printf("Testing sending %u packets of various sizes:\n", num_packets);
+        strm.Flush();
+
+        uint32_t result_idx = 0;
+        uint32_t send_size;
+        std::vector<float> packet_times;
+
+        for (send_size = 0; send_size <= max_send; send_size ? send_size *= 2 : send_size = 4)
+        {
+            for (uint32_t recv_size = 0; recv_size <= max_recv; recv_size ? recv_size *= 2 : recv_size = 4)
+            {
+                MakeSpeedTestPacket (packet, send_size, recv_size);
+
+                packet_times.clear();
+                // Test how long it takes to send 'num_packets' packets
+                start_time = TimeValue::Now();
+                for (i=0; i<num_packets; ++i)
                 {
-                    if (bytes_left >= 26)
-                    {
-                        packet.PutCString("abcdefghijklmnopqrstuvwxyz");
-                        bytes_left -= 26;
-                    }
-                    else
-                    {
-                        packet.Printf ("%*.*s;", bytes_left, bytes_left, "abcdefghijklmnopqrstuvwxyz");
-                        bytes_left = 0;
-                    }
+                    TimeValue packet_start_time = TimeValue::Now();
+                    StringExtractorGDBRemote response;
+                    SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false);
+                    TimeValue packet_end_time = TimeValue::Now();
+                    uint64_t packet_time_nsec = packet_end_time.GetAsNanoSecondsSinceJan1_1970() - packet_start_time.GetAsNanoSecondsSinceJan1_1970();
+                    packet_times.push_back((float)packet_time_nsec);
                 }
+                end_time = TimeValue::Now();
+                total_time_nsec = end_time.GetAsNanoSecondsSinceJan1_1970() - start_time.GetAsNanoSecondsSinceJan1_1970();
 
-                start_time = TimeValue::Now();
-                if (recv_size == 0)
+                float packets_per_second = (((float)num_packets)/(float)total_time_nsec) * (float)TimeValue::NanoSecPerSec;
+                float total_ms = (float)total_time_nsec/(float)TimeValue::NanoSecPerMilliSec;
+                float average_ms_per_packet = total_ms / num_packets;
+                const float standard_deviation = calculate_standard_deviation<float>(packet_times);
+                if (json)
                 {
-                    for (i=0; i<num_packets; ++i)
-                    {
-                        StringExtractorGDBRemote response;
-                        SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false);
-                    }
+                    strm.Printf ("%s\n     {\"send_size\" : %6" PRIu32 ", \"recv_size\" : %6" PRIu32 ", \"total_time_nsec\" : %12" PRIu64 ", \"standard_deviation_nsec\" : %9" PRIu64 " }", result_idx > 0 ? "," : "", send_size, recv_size, total_time_nsec, (uint64_t)standard_deviation);
+                    ++result_idx;
                 }
                 else
                 {
-                    uint32_t bytes_read = 0;
-                    while (bytes_read < k_recv_amount)
-                    {
-                        StringExtractorGDBRemote response;
-                        SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false);
-                        bytes_read += recv_size;
-                    }
+                    strm.Printf ("qSpeedTest(send=%-7u, recv=%-7u) in %" PRIu64 ".%9.9" PRIu64 " sec for %9.2f packets/sec (%10.6f ms per packet) with standard deviation of %10.6f ms\n",
+                                 send_size,
+                                 recv_size,
+                                 total_time_nsec / TimeValue::NanoSecPerSec,
+                                 total_time_nsec % TimeValue::NanoSecPerSec,
+                                 packets_per_second,
+                                 average_ms_per_packet,
+                                 standard_deviation/(float)TimeValue::NanoSecPerMilliSec);
+                }
+                strm.Flush();
+            }
+        }
+
+        const uint64_t k_recv_amount = 4*1024*1024; // Receive amount in bytes
+
+        const float k_recv_amount_mb = (float)k_recv_amount/(1024.0f*1024.0f);
+        if (json)
+            strm.Printf("\n    ]\n  },\n  \"download_speed\" : {\n    \"byte_size\" : %" PRIu64 ",\n    \"results\" : [", k_recv_amount);
+        else
+            strm.Printf("Testing receiving %2.1fMB of data using varying receive packet sizes:\n", k_recv_amount_mb);
+        strm.Flush();
+        send_size = 0;
+        result_idx = 0;
+        for (uint32_t recv_size = 32; recv_size <= max_recv; recv_size *= 2)
+        {
+            MakeSpeedTestPacket (packet, send_size, recv_size);
+
+            // If we have a receive size, test how long it takes to receive 4MB of data
+            if (recv_size > 0)
+            {
+                start_time = TimeValue::Now();
+                uint32_t bytes_read = 0;
+                uint32_t packet_count = 0;
+                while (bytes_read < k_recv_amount)
+                {
+                    StringExtractorGDBRemote response;
+                    SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false);
+                    bytes_read += recv_size;
+                    ++packet_count;
                 }
                 end_time = TimeValue::Now();
                 total_time_nsec = end_time.GetAsNanoSecondsSinceJan1_1970() - start_time.GetAsNanoSecondsSinceJan1_1970();
-                if (recv_size == 0)
+                float mb_second = ((((float)k_recv_amount)/(float)total_time_nsec) * (float)TimeValue::NanoSecPerSec) / (1024.0*1024.0);
+                float packets_per_second = (((float)packet_count)/(float)total_time_nsec) * (float)TimeValue::NanoSecPerSec;
+                float total_ms = (float)total_time_nsec/(float)TimeValue::NanoSecPerMilliSec;
+                float average_ms_per_packet = total_ms / packet_count;
+
+                if (json)
                 {
-                    float packets_per_second = (((float)num_packets)/(float)total_time_nsec) * (float)TimeValue::NanoSecPerSec;
-                    printf ("%u qSpeedTest(send=%-7u, recv=%-7u) in %" PRIu64 ".%9.9" PRIu64 " sec for %f packets/sec.\n",
-                            num_packets, 
-                            send_size,
-                            recv_size,
-                            total_time_nsec / TimeValue::NanoSecPerSec,
-                            total_time_nsec % TimeValue::NanoSecPerSec, 
-                            packets_per_second);
+                    strm.Printf ("%s\n     {\"send_size\" : %6" PRIu32 ", \"recv_size\" : %6" PRIu32 ", \"total_time_nsec\" : %12" PRIu64 " }", result_idx > 0 ? "," : "", send_size, recv_size, total_time_nsec);
+                    ++result_idx;
                 }
                 else
                 {
-                    float mb_second = ((((float)k_recv_amount)/(float)total_time_nsec) * (float)TimeValue::NanoSecPerSec) / (1024.0*1024.0);
-                    printf ("%u qSpeedTest(send=%-7u, recv=%-7u) sent 4MB in %" PRIu64 ".%9.9" PRIu64 " sec for %f MB/sec.\n",
-                            num_packets,
-                            send_size,
-                            recv_size,
-                            total_time_nsec / TimeValue::NanoSecPerSec,
-                            total_time_nsec % TimeValue::NanoSecPerSec,
-                            mb_second);
+                    strm.Printf ("qSpeedTest(send=%-7u, recv=%-7u) %6u packets needed to receive %2.1fMB in %" PRIu64 ".%9.9" PRIu64 " sec for %f MB/sec for %9.2f packets/sec (%10.6f ms per packet)\n",
+                                 send_size,
+                                 recv_size,
+                                 packet_count,
+                                 k_recv_amount_mb,
+                                 total_time_nsec / TimeValue::NanoSecPerSec,
+                                 total_time_nsec % TimeValue::NanoSecPerSec,
+                                 mb_second,
+                                 packets_per_second,
+                                 average_ms_per_packet);
                 }
+                strm.Flush();
             }
         }
+        if (json)
+            strm.Printf("\n    ]\n  }\n}\n");
+        else
+            strm.EOL();
     }
 }
 

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h?rev=237953&r1=237952&r2=237953&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h Thu May 21 15:52:06 2015
@@ -400,7 +400,7 @@ public:
     SetNonStopMode (const bool enable);
 
     void
-    TestPacketSpeed (const uint32_t num_packets);
+    TestPacketSpeed (const uint32_t num_packets, uint32_t max_send, uint32_t max_recv, bool json, Stream &strm);
 
     // This packet is for testing the speed of the interface only. Both
     // the client and server need to support it, but this allows us to

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp?rev=237953&r1=237952&r2=237953&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp Thu May 21 15:52:06 2015
@@ -55,6 +55,9 @@
 #include "lldb/Interpreter/CommandObjectMultiword.h"
 #include "lldb/Interpreter/CommandReturnObject.h"
 #include "lldb/Interpreter/OptionValueProperties.h"
+#include "lldb/Interpreter/Options.h"
+#include "lldb/Interpreter/OptionGroupBoolean.h"
+#include "lldb/Interpreter/OptionGroupUInt64.h"
 #include "lldb/Interpreter/Property.h"
 #include "lldb/Symbol/ObjectFile.h"
 #include "lldb/Target/DynamicLoader.h"
@@ -4311,6 +4314,80 @@ ProcessGDBRemote::LoadModules ()
     return new_modules.GetSize();
 }
 
+class CommandObjectProcessGDBRemoteSpeedTest: public CommandObjectParsed
+{
+public:
+    CommandObjectProcessGDBRemoteSpeedTest(CommandInterpreter &interpreter) :
+        CommandObjectParsed (interpreter,
+                             "process plugin packet speed-test",
+                             "Tests packet speeds of various sizes to determine the performance characteristics of the GDB remote connection. ",
+                             NULL),
+        m_option_group (interpreter),
+        m_num_packets (LLDB_OPT_SET_1, false, "count",       'c', 0, eArgTypeCount, "The number of packets to send of each varying size (default is 1000).", 1000),
+        m_max_send    (LLDB_OPT_SET_1, false, "max-send",    's', 0, eArgTypeCount, "The maximum number of bytes to send in a packet. Sizes increase in powers of 2 while the size is less than or equal to this option value. (default 1024).", 1024),
+        m_max_recv    (LLDB_OPT_SET_1, false, "max-receive", 'r', 0, eArgTypeCount, "The maximum number of bytes to receive in a packet. Sizes increase in powers of 2 while the size is less than or equal to this option value. (default 1024).", 1024),
+        m_json        (LLDB_OPT_SET_1, false, "json",        'j', "Print the output as JSON data for easy parsing.", false, true)
+    {
+        m_option_group.Append (&m_num_packets, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
+        m_option_group.Append (&m_max_send, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
+        m_option_group.Append (&m_max_recv, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
+        m_option_group.Append (&m_json, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
+        m_option_group.Finalize();
+    }
+
+    ~CommandObjectProcessGDBRemoteSpeedTest ()
+    {
+    }
+
+
+    Options *
+    GetOptions () override
+    {
+        return &m_option_group;
+    }
+
+    bool
+    DoExecute (Args& command, CommandReturnObject &result) override
+    {
+        const size_t argc = command.GetArgumentCount();
+        if (argc == 0)
+        {
+            ProcessGDBRemote *process = (ProcessGDBRemote *)m_interpreter.GetExecutionContext().GetProcessPtr();
+            if (process)
+            {
+                StreamSP output_stream_sp (m_interpreter.GetDebugger().GetAsyncOutputStream());
+                result.SetImmediateOutputStream (output_stream_sp);
+
+                const uint32_t num_packets = (uint32_t)m_num_packets.GetOptionValue().GetCurrentValue();
+                const uint64_t max_send = m_max_send.GetOptionValue().GetCurrentValue();
+                const uint64_t max_recv = m_max_recv.GetOptionValue().GetCurrentValue();
+                const bool json = m_json.GetOptionValue().GetCurrentValue();
+                if (output_stream_sp)
+                    process->GetGDBRemote().TestPacketSpeed (num_packets, max_send, max_recv, json, *output_stream_sp);
+                else
+                {
+                    process->GetGDBRemote().TestPacketSpeed (num_packets, max_send, max_recv, json, result.GetOutputStream());
+                }
+                result.SetStatus (eReturnStatusSuccessFinishResult);
+                return true;
+            }
+        }
+        else
+        {
+            result.AppendErrorWithFormat ("'%s' takes no arguments", m_cmd_name.c_str());
+        }
+        result.SetStatus (eReturnStatusFailed);
+        return false;
+    }
+protected:
+    OptionGroupOptions m_option_group;
+    OptionGroupUInt64 m_num_packets;
+    OptionGroupUInt64 m_max_send;
+    OptionGroupUInt64 m_max_recv;
+    OptionGroupBoolean m_json;
+
+};
+
 class CommandObjectProcessGDBRemotePacketHistory : public CommandObjectParsed
 {
 private:
@@ -4524,6 +4601,7 @@ public:
         LoadSubCommand ("send", CommandObjectSP (new CommandObjectProcessGDBRemotePacketSend (interpreter)));
         LoadSubCommand ("monitor", CommandObjectSP (new CommandObjectProcessGDBRemotePacketMonitor (interpreter)));
         LoadSubCommand ("xfer-size", CommandObjectSP (new CommandObjectProcessGDBRemotePacketXferSize (interpreter)));
+        LoadSubCommand ("speed-test", CommandObjectSP (new CommandObjectProcessGDBRemoteSpeedTest (interpreter)));
     }
     
     ~CommandObjectProcessGDBRemotePacket ()





More information about the lldb-commits mailing list