Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Performance of QUdpSocket writeDatagram between Qt4 and Qt5 in different GNU/Linux platforms

Performance of QUdpSocket writeDatagram between Qt4 and Qt5 in different GNU/Linux platforms

Scheduled Pinned Locked Moved General and Desktop
7 Posts 3 Posters 3.0k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    malloblenne
    wrote on last edited by
    #1

    Hello,

    I am facing an unusual behaviour related to the performance of the method writeDatagram of QUdpSocket using two different version of QT ( Qt4.8.5 vs Qt5.1.1).

    I tested the same program both on Ubuntu between 4.8.1 and 5.0 and the results are fine.
    While on an emDebian arm platform, Qt5.1.1 performs much worse than Qt4.8.5 (two order of magnitude times slower).

    Basically, my application is just calling writeDatagram in a for loop and returns the average time writeDatagram calls.
    The results after 10000 calls, sending 19bytes of payload are:
    Qt 4.8.5 avg 0.000224s each call
    Qt 5.1.1 avg 0.033..s (about 30ms each message).

    I checked in Wireshark and I am able to receive the messages in both cases.
    Moreover, I tested vanilla c socket and they perform as good as qt 4.8.5.
    I wonder how it is possible, and if you have any suggestion in merit.
    I looked a bit in the qt code and saw a bind() inside the QT5 writeDatagram method, which I do not immediately understand but I do not know if might cause the issue.
    Should I specify something more in the initialization of the QUdpSocket? Are there any pauses, wait or blocking mechanisms?
    Might my ethernet interface configuration be wrong? How should I adjust it in that case?

    Regards,

    Below is my code:

    //Util.h
    #pragma once
    #ifdef linux
    #include <time.h>
    #else
    #define NOMINMAX
    #include <windows.h>
    #include <time.h>
    #endif

    class Util
    {
    public:
    inline static float GetTimeSeconds(void)
    {
    #ifdef linux
    static bool initialized = false;
    static struct timespec offsetTime;
    struct timespec startTime;
    clock_gettime( CLOCK_MONOTONIC, &startTime);
    if (!initialized)
    {
    offsetTime.tv_sec = startTime.tv_sec;
    offsetTime.tv_nsec = startTime.tv_nsec;
    initialized = true;
    }
    return static_cast<float>( (startTime.tv_sec - offsetTime.tv_sec) + (startTime.tv_nsec - offsetTime.tv_nsec)/1.0e9);
    #else
    return static_cast<float>(clock())/ static_cast<float>(CLOCKS_PER_SEC);
    #endif
    }
    };

    //Task.h
    #pragma once
    #include <QtCore>
    #include <QtNetwork>
    #include <QUdpSocket>
    #include "Util.h"

    class Task : public QObject
    {
    Q_OBJECT
    public:
    Task(QObject *parent = 0) : QObject(parent) {}

    public slots:
    void run()
    {
    // Do processing here
    unsigned int messageNo = 0;
    QUdpSocket *udpSocket;
    udpSocket = new QUdpSocket(this);
    int times = 10000;
    QByteArray datagram = "Broadcast message " + QByteArray::number(messageNo);
    const double t1 = Util::GetTimeSeconds();
    for (int i = 0; i<times; i++)
    {
    udpSocket->writeDatagram(datagram.data(), datagram.size(), QHostAddress::Broadcast, 45454);
    }
    const double t2 = Util::GetTimeSeconds();
    qDebug(" writeDatagram(): %f s, total %f", (t2 - t1)/times, (t2 - t1));//dt
    ++messageNo;
    emit finished();
    delete udpSocket;
    }

    signals:
    void finished();
    };

    // main.cpp
    #include "Task.h"
    int main(int argc, char *argv[])
    {
    QCoreApplication a(argc, argv);
    Task *task = new Task(&a);
    QObject::connect(task, SIGNAL(finished()), &a, SLOT(quit()));
    QTimer::singleShot(0, task, SLOT(run()));
    return a.exec();
    }

    1 Reply Last reply
    0
    • sierdzioS Offline
      sierdzioS Offline
      sierdzio
      Moderators
      wrote on last edited by
      #2

      Hi and thank you for that analysis. I think people on the development "mailing list":http://lists.qt-project.org/mailman/listinfo might be more interested (that is where hardcore Qt devs are; this forum focuses on users of Qt).

      (Z(:^

      1 Reply Last reply
      0
      • M Offline
        M Offline
        malloblenne
        wrote on last edited by
        #3

        Thank you sierdzio.
        I will repost it there.

        1 Reply Last reply
        0
        • sierdzioS Offline
          sierdzioS Offline
          sierdzio
          Moderators
          wrote on last edited by
          #4

          Nice to see the amount of interest your post is getting. If you are lucky, the bug will be fixed soon.

          For future reference: "here":https://bugreports.qt-project.org/browse/QTBUG-37092 is the bug report.

          (Z(:^

          1 Reply Last reply
          0
          • J Offline
            J Offline
            johnthesoftware
            wrote on last edited by
            #5

            I can confirm that this problem exists running bsquask (Qt specific embedded/cross compiler for the RPi)

            I've completely lost track of where this problem is being pursued so it may be fixed by now.

            Someone suggested that it may be a re-bind issue. I can confirm that binding to a local device address (not localhost) before using the socket seems to fix it.

            1 Reply Last reply
            0
            • M Offline
              M Offline
              malloblenne
              wrote on last edited by
              #6

              Hi,

              I am still interesting in solving the issue in my code.
              To overcome that problem I have just used C raw socket but it is not an elegant solution.

              I did not understand completely what you mean when you are writing about binding to another local address.

              Do you mean I should call twice the function bind with different parameters or just once with the local address one?

              I use the following syntax:

              QUdpSocket* myUdpSocket = new QUdpSocket(this);
              myUdpSocket->bind(QHostAddress(QHostAddress::Any), (quint16)0)

              Should I replace the QHostAddress::Any with my address like 192.168.1.x

              I also do not get why if it is a binding issue it affects the sending (UDP) and not the receiving part.

              1 Reply Last reply
              0
              • J Offline
                J Offline
                johnthesoftware
                wrote on last edited by
                #7

                My code reads

                QUdpSocket* myUdpSocket = new QUdpSocket(this);
                myUdpSocket->bind(QHostAddress("192.168.0.31"), 3000);

                then

                while(true)
                writeDatagram(etc..

                192.168.0.31 is the address of my NIC, 3000 is the remote receipt port which is probably irrelevant.

                Without bind() writeDatagram takes 25mS, with bind() the delay is nominal.

                I don't understand the sending thing either, but hey, it's a bug.

                1 Reply Last reply
                0

                • Login

                • Login or register to search.
                • First post
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • Users
                • Groups
                • Search
                • Get Qt Extensions
                • Unsolved