usrp-users@lists.ettus.com

Discussion and technical support related to USRP, UHD, RFNoC

View all threads

x310 Not Sending Jumbo Packets (>8000 bytes) as 1 Packet on 10GigE

C
cjohnson@serranosystems.com
Tue, Jun 18, 2024 4:18 AM

Would you be able to provide some suggestions?  We need to keep precision timing for transmission.  Neither of the two proof of concepts (POC) below are meeting our needs.  Of course we are sending 2 packets due to lack of jumbo frames.

We have 2048 samples (4 bytes per sample) we would have liked to send per packet, or 2048/200E+6 = 10.24 us per packet or 97656 packets per second.  It’s a continuous stream.  This doesn’t include packet overhead.

The reason the Jumbo frame thing came up was because we were getting “L”s (missed timing) when using the time spec, and “U” when not using timing spec, most likely due to 2 packets per transmission instead of 1 jumbo frame.

I have provided POC of our test Tx program for 2 cases.  The first uses timing spec, which doesn’t keep up.  The second was just to see how it would perform if there wasn’t a time spec.

This thread runs as the highest priority in Linux, and we have tuned according to your documentation.

First Test Program 1), PPS is ~95500,  but we get “L”s constantly .

[INFO] [UHD] linux; GNU C++ version 9.4.0; Boost_107100; UHD_
[INFO] [X300] X300 initialization sequence...
[INFO] [X300] Maximum frame size: 8000 bytes.
[INFO] [GPS] Found an internal GPSDO: LC_XO, Firmware Rev 0.929a
[INFO] [X300] Radio 1x clock: 200 MHz
Actual TX Rate: 200.000000 Msps
Actual TX Freq: 2400.000000 MHz
Actual TX Gain: 30.000000 dB
Actual TX Bandwidth: 16.000000 MHz
[WARNING] [0/Radio#0] Attempting to set tick rate to 0. Skipping.
Using transmit_packets_timespec()
Start transmit_packets_timespec()
Packet size: 8192 bytes
--------------------------------------------
Transmitted packets: 30632386
Dropped packets: 9
PAUSE frames received: 0
PAUSE frames transmitted: 0
GPS lock lost events: 0
Network RX packets: 19733243
Network TX packets: 206298940
Network RX errors: 0
Network TX errors: 0
Network RX dropped: 0
Network TX dropped: 0
USRP TX overruns: 0
USRP TX underruns: 0
USRP sequence errors: 0
GPS time sync: 1136281795
GPS time sync errors: 0
Packets Per Second (PPS): 95428  

Second Test Program 2), PPS is ~98000, Buffer Size is 8192 (without USRP overhead), occasional “U”

[INFO] [UHD] linux; GNU C++ version 9.4.0; Boost_107100; UHD_
[INFO] [X300] X300 initialization sequence...
[INFO] [X300] Maximum frame size: 8000 bytes.
[INFO] [GPS] Found an internal GPSDO: LC_XO, Firmware Rev 0.929a
[INFO] [X300] Radio 1x clock: 200 MHz
Actual TX Rate: 200.000000 Msps
Actual TX Freq: 2400.000000 MHz
Actual TX Gain: 30.000000 dB
Actual TX Bandwidth: 16.000000 MHz
[WARNING] [0/Radio#0] Attempting to set tick rate to 0. Skipping.
Using transmit_packets_no_timespec()
Start transmit_packets_no_timespec()
Packet size: 8192 bytes
--------------------------------------------
Transmitted packets: 12844561
Dropped packets: 0
PAUSE frames received: 0
PAUSE frames transmitted: 0
GPS lock lost events: 0
Network RX packets: 5528620
Network TX packets: 77280212
Network RX errors: 0
Network TX errors: 0
Network RX dropped: 0
Network TX dropped: 0
USRP TX overruns: 0
USRP TX underruns: 0
USRP sequence errors: 0
GPS time sync: 1136280963
GPS time sync errors: 0
Packets Per Second (PPS): 98050

// 2 function to simulate our packet transmission
// First Test Program 1)
void transmit_packets_timespec(uhd::usrp::multi_usrp::sptr usrp, uhd::tx_streamer::sptr tx_stream, std::atomic<bool> &gps_locked, double rate) {
    uhd::tx_metadata_t md;
    md.start_of_burst = true;
    md.end_of_burst = false;
    md.has_time_spec = true;

    std::vector<std::complex<int16_t>> buffer(2048); // CRJ TEMP buffer(2048);

    std::cout << "Start transmit_packets_timespec()" << std::endl;
    std::cout << "Packet size: " << buffer.size() * sizeof(std::complex<int16_t>) << " bytes" << std::endl;

    // Get and print the maximum number of samples per packet
    size_t max_num_samps = tx_stream->get_max_num_samps();
    std::cout << "Max number of samples per packet: " << max_num_samps << std::endl;

    // Initialize timestamp
    md.time_spec = uhd::time_spec_t(usrp->get_time_now().get_full_secs() + 1.0); // Start 1 second in the future

    while (1 /*!stop_logging.load()*/) {
        //if (gps_locked.load()) {
            //  md.time_spec = uhd::time_spec_t(usrp->get_time_now().get_full_secs() + 1.0);
        //}

        size_t num_tx_samps = tx_stream->send(&buffer.front(), buffer.size(), md);

        if (num_tx_samps < buffer.size()) {
            dropped_packets++;
        } else {
            transmitted_packets++;
        }

        md.time_spec = md.time_spec + uhd::time_spec_t(buffer.size() / rate);

        md.start_of_burst = false;
        //std::this_thread::sleep_for(std::chrono::milliseconds(5));
    }

    // Mark end of burst
    md.end_of_burst = true;
    tx_stream->send("", 0, md);
}

// Second Test Program 2)
void transmit_packets_no_timespec(uhd::usrp::multi_usrp::sptr usrp, uhd::tx_streamer::sptr tx_stream, std::atomic<bool> &gps_locked, double rate) {
    uhd::tx_metadata_t md;
    md.start_of_burst = true;
    md.end_of_burst = false;
    md.has_time_spec = false; // No time specification

    std::vector<std::complex<int16_t>> buffer(2048);

    std::cout << "Start transmit_packets_no_timespec()" << std::endl;
    std::cout << "Packet size: " << buffer.size() * sizeof(std::complex<int16_t>) << " bytes" << std::endl;

    while (!stop_logging.load()) {
        size_t num_tx_samps = tx_stream->send(&buffer.front(), buffer.size(), md);

        if (num_tx_samps < buffer.size()) {
            dropped_packets++;
        } else {
            transmitted_packets++;
        }

        md.start_of_burst = false;
        // Adjust the sleep time to control the packet rate
        // std::this_thread::sleep_for(std::chrono::milliseconds(1));
    }

    // Mark end of burst
    md.end_of_burst = true;
    tx_stream->send("", 0, md);
}
Would you be able to provide some suggestions? We need to keep precision timing for transmission. Neither of the two proof of concepts (POC) below are meeting our needs. Of course we are sending 2 packets due to lack of jumbo frames. We have 2048 samples (4 bytes per sample) we would have liked to send per packet, or 2048/200E+6 = 10.24 us per packet or 97656 packets per second. It’s a continuous stream. This doesn’t include packet overhead. The reason the Jumbo frame thing came up was because we were getting “L”s (missed timing) when using the time spec, and “U” when not using timing spec, most likely due to 2 packets per transmission instead of 1 jumbo frame. I have provided POC of our test Tx program for 2 cases. The first uses timing spec, which doesn’t keep up. The second was just to see how it would perform if there wasn’t a time spec. This thread runs as the highest priority in Linux, and we have tuned according to your documentation. ***First Test Program 1), PPS is \~95500,  but we get “L”s constantly .*** ``` [INFO] [UHD] linux; GNU C++ version 9.4.0; Boost_107100; UHD_ ``` ``` [INFO] [X300] X300 initialization sequence... ``` ``` [INFO] [X300] Maximum frame size: 8000 bytes. ``` ``` [INFO] [GPS] Found an internal GPSDO: LC_XO, Firmware Rev 0.929a ``` ``` [INFO] [X300] Radio 1x clock: 200 MHz ``` ``` Actual TX Rate: 200.000000 Msps ``` ``` Actual TX Freq: 2400.000000 MHz ``` ``` Actual TX Gain: 30.000000 dB ``` ``` Actual TX Bandwidth: 16.000000 MHz ``` ``` [WARNING] [0/Radio#0] Attempting to set tick rate to 0. Skipping. ``` ``` Using transmit_packets_timespec() ``` ``` Start transmit_packets_timespec() ``` ``` Packet size: 8192 bytes ``` ``` -------------------------------------------- ``` ``` Transmitted packets: 30632386 ``` ``` Dropped packets: 9 ``` ``` PAUSE frames received: 0 ``` ``` PAUSE frames transmitted: 0 ``` ``` GPS lock lost events: 0 ``` ``` Network RX packets: 19733243 ``` ``` Network TX packets: 206298940 ``` ``` Network RX errors: 0 ``` ``` Network TX errors: 0 ``` ``` Network RX dropped: 0 ``` ``` Network TX dropped: 0 ``` ``` USRP TX overruns: 0 ``` ``` USRP TX underruns: 0 ``` ``` USRP sequence errors: 0 ``` ``` GPS time sync: 1136281795 ``` ``` GPS time sync errors: 0 ``` ``` Packets Per Second (PPS): 95428 ``` **Second Test Program 2), PPS is \~98000, Buffer Size is 8192 (without USRP overhead), occasional “U”** ``` [INFO] [UHD] linux; GNU C++ version 9.4.0; Boost_107100; UHD_ ``` ``` [INFO] [X300] X300 initialization sequence... ``` ``` [INFO] [X300] Maximum frame size: 8000 bytes. ``` ``` [INFO] [GPS] Found an internal GPSDO: LC_XO, Firmware Rev 0.929a ``` ``` [INFO] [X300] Radio 1x clock: 200 MHz ``` ``` Actual TX Rate: 200.000000 Msps ``` ``` Actual TX Freq: 2400.000000 MHz ``` ``` Actual TX Gain: 30.000000 dB ``` ``` Actual TX Bandwidth: 16.000000 MHz ``` ``` [WARNING] [0/Radio#0] Attempting to set tick rate to 0. Skipping. ``` ``` Using transmit_packets_no_timespec() ``` ``` Start transmit_packets_no_timespec() ``` ``` Packet size: 8192 bytes ``` ``` -------------------------------------------- ``` ``` Transmitted packets: 12844561 ``` ``` Dropped packets: 0 ``` ``` PAUSE frames received: 0 ``` ``` PAUSE frames transmitted: 0 ``` ``` GPS lock lost events: 0 ``` ``` Network RX packets: 5528620 ``` ``` Network TX packets: 77280212 ``` ``` Network RX errors: 0 ``` ``` Network TX errors: 0 ``` ``` Network RX dropped: 0 ``` ``` Network TX dropped: 0 ``` ``` USRP TX overruns: 0 ``` ``` USRP TX underruns: 0 ``` ``` USRP sequence errors: 0 ``` ``` GPS time sync: 1136280963 ``` ``` GPS time sync errors: 0 ``` ``` Packets Per Second (PPS): 98050 ``` ``` // 2 function to simulate our packet transmission // First Test Program 1) void transmit_packets_timespec(uhd::usrp::multi_usrp::sptr usrp, uhd::tx_streamer::sptr tx_stream, std::atomic<bool> &gps_locked, double rate) { uhd::tx_metadata_t md; md.start_of_burst = true; md.end_of_burst = false; md.has_time_spec = true; std::vector<std::complex<int16_t>> buffer(2048); // CRJ TEMP buffer(2048); std::cout << "Start transmit_packets_timespec()" << std::endl; std::cout << "Packet size: " << buffer.size() * sizeof(std::complex<int16_t>) << " bytes" << std::endl; // Get and print the maximum number of samples per packet size_t max_num_samps = tx_stream->get_max_num_samps(); std::cout << "Max number of samples per packet: " << max_num_samps << std::endl; // Initialize timestamp md.time_spec = uhd::time_spec_t(usrp->get_time_now().get_full_secs() + 1.0); // Start 1 second in the future while (1 /*!stop_logging.load()*/) { //if (gps_locked.load()) { // md.time_spec = uhd::time_spec_t(usrp->get_time_now().get_full_secs() + 1.0); //} size_t num_tx_samps = tx_stream->send(&buffer.front(), buffer.size(), md); if (num_tx_samps < buffer.size()) { dropped_packets++; } else { transmitted_packets++; } md.time_spec = md.time_spec + uhd::time_spec_t(buffer.size() / rate); md.start_of_burst = false; //std::this_thread::sleep_for(std::chrono::milliseconds(5)); } // Mark end of burst md.end_of_burst = true; tx_stream->send("", 0, md); } // Second Test Program 2) void transmit_packets_no_timespec(uhd::usrp::multi_usrp::sptr usrp, uhd::tx_streamer::sptr tx_stream, std::atomic<bool> &gps_locked, double rate) { uhd::tx_metadata_t md; md.start_of_burst = true; md.end_of_burst = false; md.has_time_spec = false; // No time specification std::vector<std::complex<int16_t>> buffer(2048); std::cout << "Start transmit_packets_no_timespec()" << std::endl; std::cout << "Packet size: " << buffer.size() * sizeof(std::complex<int16_t>) << " bytes" << std::endl; while (!stop_logging.load()) { size_t num_tx_samps = tx_stream->send(&buffer.front(), buffer.size(), md); if (num_tx_samps < buffer.size()) { dropped_packets++; } else { transmitted_packets++; } md.start_of_burst = false; // Adjust the sleep time to control the packet rate // std::this_thread::sleep_for(std::chrono::milliseconds(1)); } // Mark end of burst md.end_of_burst = true; tx_stream->send("", 0, md); } ```
WF
Wade Fife
Tue, Jun 18, 2024 8:40 PM

For the first version can you try setting has_time_spec to false after the
first packet is sent, and don't bother to set the time_spec on subsequent
packets within a burst? The time_spec should really only be for the first
packet. The radio will ignore the timestamp on the subsequent packets
within a burst, and I noticed we set has_time_spec to false after the first
packet in our benchmark_rate example.

L means the first packet of the burst came after the indicated time, and 1
second should be enough time. So I suspect either the time is being
calculated wrong or you're sending multiple bursts. If a subsequent packet
in a burst comes late, it would show up as a U rather than L.

Wade

On Mon, Jun 17, 2024 at 11:18 PM cjohnson@serranosystems.com wrote:

Would you be able to provide some suggestions? We need to keep precision
timing for transmission. Neither of the two proof of concepts (POC) below
are meeting our needs. Of course we are sending 2 packets due to lack of
jumbo frames.

We have 2048 samples (4 bytes per sample) we would have liked to send per
packet, or 2048/200E+6 = 10.24 us per packet or 97656 packets per second.
It’s a continuous stream. This doesn’t include packet overhead.

The reason the Jumbo frame thing came up was because we were getting “L”s
(missed timing) when using the time spec, and “U” when not using timing
spec, most likely due to 2 packets per transmission instead of 1 jumbo
frame.

I have provided POC of our test Tx program for 2 cases. The first uses
timing spec, which doesn’t keep up. The second was just to see how it would
perform if there wasn’t a time spec.

This thread runs as the highest priority in Linux, and we have tuned
according to your documentation.

First Test Program 1), PPS is ~95500,  but we get “L”s constantly .

[INFO] [UHD] linux; GNU C++ version 9.4.0; Boost_107100; UHD_

[INFO] [X300] X300 initialization sequence...

[INFO] [X300] Maximum frame size: 8000 bytes.

[INFO] [GPS] Found an internal GPSDO: LC_XO, Firmware Rev 0.929a

[INFO] [X300] Radio 1x clock: 200 MHz

Actual TX Rate: 200.000000 Msps

Actual TX Freq: 2400.000000 MHz

Actual TX Gain: 30.000000 dB

Actual TX Bandwidth: 16.000000 MHz

[WARNING] [0/Radio#0] Attempting to set tick rate to 0. Skipping.

Using transmit_packets_timespec()

Start transmit_packets_timespec()

Packet size: 8192 bytes


Transmitted packets: 30632386

Dropped packets: 9

PAUSE frames received: 0

PAUSE frames transmitted: 0

GPS lock lost events: 0

Network RX packets: 19733243

Network TX packets: 206298940

Network RX errors: 0

Network TX errors: 0

Network RX dropped: 0

Network TX dropped: 0

USRP TX overruns: 0

USRP TX underruns: 0

USRP sequence errors: 0

GPS time sync: 1136281795

GPS time sync errors: 0

Packets Per Second (PPS): 95428

Second Test Program 2), PPS is ~98000, Buffer Size is 8192 (without USRP
overhead), occasional “U”

[INFO] [UHD] linux; GNU C++ version 9.4.0; Boost_107100; UHD_

[INFO] [X300] X300 initialization sequence...

[INFO] [X300] Maximum frame size: 8000 bytes.

[INFO] [GPS] Found an internal GPSDO: LC_XO, Firmware Rev 0.929a

[INFO] [X300] Radio 1x clock: 200 MHz

Actual TX Rate: 200.000000 Msps

Actual TX Freq: 2400.000000 MHz

Actual TX Gain: 30.000000 dB

Actual TX Bandwidth: 16.000000 MHz

[WARNING] [0/Radio#0] Attempting to set tick rate to 0. Skipping.

Using transmit_packets_no_timespec()

Start transmit_packets_no_timespec()

Packet size: 8192 bytes


Transmitted packets: 12844561

Dropped packets: 0

PAUSE frames received: 0

PAUSE frames transmitted: 0

GPS lock lost events: 0

Network RX packets: 5528620

Network TX packets: 77280212

Network RX errors: 0

Network TX errors: 0

Network RX dropped: 0

Network TX dropped: 0

USRP TX overruns: 0

USRP TX underruns: 0

USRP sequence errors: 0

GPS time sync: 1136280963

GPS time sync errors: 0

Packets Per Second (PPS): 98050

// 2 function to simulate our packet transmission
// First Test Program 1)
void transmit_packets_timespec(uhd::usrp::multi_usrp::sptr usrp, uhd::tx_streamer::sptr tx_stream, std::atomic<bool> &gps_locked, double rate) {
uhd::tx_metadata_t md;
md.start_of_burst = true;
md.end_of_burst = false;
md.has_time_spec = true;

 std::vector<std::complex<int16_t>> buffer(2048); // CRJ TEMP buffer(2048);

 std::cout << "Start transmit_packets_timespec()" << std::endl;
 std::cout << "Packet size: " << buffer.size() * sizeof(std::complex<int16_t>) << " bytes" << std::endl;

 // Get and print the maximum number of samples per packet
 size_t max_num_samps = tx_stream->get_max_num_samps();
 std::cout << "Max number of samples per packet: " << max_num_samps << std::endl;

 // Initialize timestamp
 md.time_spec = uhd::time_spec_t(usrp->get_time_now().get_full_secs() + 1.0); // Start 1 second in the future

 while (1 /*!stop_logging.load()*/) {
     //if (gps_locked.load()) {
         //  md.time_spec = uhd::time_spec_t(usrp->get_time_now().get_full_secs() + 1.0);
     //}

     size_t num_tx_samps = tx_stream->send(&buffer.front(), buffer.size(), md);

     if (num_tx_samps < buffer.size()) {
         dropped_packets++;
     } else {
         transmitted_packets++;
     }

     md.time_spec = md.time_spec + uhd::time_spec_t(buffer.size() / rate);

     md.start_of_burst = false;
     //std::this_thread::sleep_for(std::chrono::milliseconds(5));
 }

 // Mark end of burst
 md.end_of_burst = true;
 tx_stream->send("", 0, md);

}

// Second Test Program 2)
void transmit_packets_no_timespec(uhd::usrp::multi_usrp::sptr usrp, uhd::tx_streamer::sptr tx_stream, std::atomic<bool> &gps_locked, double rate) {
uhd::tx_metadata_t md;
md.start_of_burst = true;
md.end_of_burst = false;
md.has_time_spec = false; // No time specification

 std::vector<std::complex<int16_t>> buffer(2048);

 std::cout << "Start transmit_packets_no_timespec()" << std::endl;
 std::cout << "Packet size: " << buffer.size() * sizeof(std::complex<int16_t>) << " bytes" << std::endl;

 while (!stop_logging.load()) {
     size_t num_tx_samps = tx_stream->send(&buffer.front(), buffer.size(), md);

     if (num_tx_samps < buffer.size()) {
         dropped_packets++;
     } else {
         transmitted_packets++;
     }

     md.start_of_burst = false;
     // Adjust the sleep time to control the packet rate
     // std::this_thread::sleep_for(std::chrono::milliseconds(1));
 }

 // Mark end of burst
 md.end_of_burst = true;
 tx_stream->send("", 0, md);

}


USRP-users mailing list -- usrp-users@lists.ettus.com
To unsubscribe send an email to usrp-users-leave@lists.ettus.com

For the first version can you try setting has_time_spec to false after the first packet is sent, and don't bother to set the time_spec on subsequent packets within a burst? The time_spec should really only be for the first packet. The radio will ignore the timestamp on the subsequent packets within a burst, and I noticed we set has_time_spec to false after the first packet in our benchmark_rate example. L means the first packet of the burst came after the indicated time, and 1 second should be enough time. So I suspect either the time is being calculated wrong or you're sending multiple bursts. If a subsequent packet in a burst comes late, it would show up as a U rather than L. Wade On Mon, Jun 17, 2024 at 11:18 PM <cjohnson@serranosystems.com> wrote: > Would you be able to provide some suggestions? We need to keep precision > timing for transmission. Neither of the two proof of concepts (POC) below > are meeting our needs. Of course we are sending 2 packets due to lack of > jumbo frames. > > We have 2048 samples (4 bytes per sample) we would have liked to send per > packet, or 2048/200E+6 = 10.24 us per packet or 97656 packets per second. > It’s a continuous stream. This doesn’t include packet overhead. > > The reason the Jumbo frame thing came up was because we were getting “L”s > (missed timing) when using the time spec, and “U” when not using timing > spec, most likely due to 2 packets per transmission instead of 1 jumbo > frame. > > I have provided POC of our test Tx program for 2 cases. The first uses > timing spec, which doesn’t keep up. The second was just to see how it would > perform if there wasn’t a time spec. > > This thread runs as the highest priority in Linux, and we have tuned > according to your documentation. > > *First Test Program 1), PPS is ~95500, but we get “L”s constantly .* > > [INFO] [UHD] linux; GNU C++ version 9.4.0; Boost_107100; UHD_ > > [INFO] [X300] X300 initialization sequence... > > [INFO] [X300] Maximum frame size: 8000 bytes. > > [INFO] [GPS] Found an internal GPSDO: LC_XO, Firmware Rev 0.929a > > [INFO] [X300] Radio 1x clock: 200 MHz > > Actual TX Rate: 200.000000 Msps > > Actual TX Freq: 2400.000000 MHz > > Actual TX Gain: 30.000000 dB > > Actual TX Bandwidth: 16.000000 MHz > > [WARNING] [0/Radio#0] Attempting to set tick rate to 0. Skipping. > > Using transmit_packets_timespec() > > Start transmit_packets_timespec() > > Packet size: 8192 bytes > > -------------------------------------------- > > Transmitted packets: 30632386 > > Dropped packets: 9 > > PAUSE frames received: 0 > > PAUSE frames transmitted: 0 > > GPS lock lost events: 0 > > Network RX packets: 19733243 > > Network TX packets: 206298940 > > Network RX errors: 0 > > Network TX errors: 0 > > Network RX dropped: 0 > > Network TX dropped: 0 > > USRP TX overruns: 0 > > USRP TX underruns: 0 > > USRP sequence errors: 0 > > GPS time sync: 1136281795 > > GPS time sync errors: 0 > > Packets Per Second (PPS): 95428 > > > *Second Test Program 2), PPS is ~98000, Buffer Size is 8192 (without USRP > overhead), occasional “U”* > > [INFO] [UHD] linux; GNU C++ version 9.4.0; Boost_107100; UHD_ > > [INFO] [X300] X300 initialization sequence... > > [INFO] [X300] Maximum frame size: 8000 bytes. > > [INFO] [GPS] Found an internal GPSDO: LC_XO, Firmware Rev 0.929a > > [INFO] [X300] Radio 1x clock: 200 MHz > > Actual TX Rate: 200.000000 Msps > > Actual TX Freq: 2400.000000 MHz > > Actual TX Gain: 30.000000 dB > > Actual TX Bandwidth: 16.000000 MHz > > [WARNING] [0/Radio#0] Attempting to set tick rate to 0. Skipping. > > Using transmit_packets_no_timespec() > > Start transmit_packets_no_timespec() > > Packet size: 8192 bytes > > -------------------------------------------- > > Transmitted packets: 12844561 > > Dropped packets: 0 > > PAUSE frames received: 0 > > PAUSE frames transmitted: 0 > > GPS lock lost events: 0 > > Network RX packets: 5528620 > > Network TX packets: 77280212 > > Network RX errors: 0 > > Network TX errors: 0 > > Network RX dropped: 0 > > Network TX dropped: 0 > > USRP TX overruns: 0 > > USRP TX underruns: 0 > > USRP sequence errors: 0 > > GPS time sync: 1136280963 > > GPS time sync errors: 0 > > Packets Per Second (PPS): 98050 > > > // 2 function to simulate our packet transmission > // First Test Program 1) > void transmit_packets_timespec(uhd::usrp::multi_usrp::sptr usrp, uhd::tx_streamer::sptr tx_stream, std::atomic<bool> &gps_locked, double rate) { > uhd::tx_metadata_t md; > md.start_of_burst = true; > md.end_of_burst = false; > md.has_time_spec = true; > > std::vector<std::complex<int16_t>> buffer(2048); // CRJ TEMP buffer(2048); > > std::cout << "Start transmit_packets_timespec()" << std::endl; > std::cout << "Packet size: " << buffer.size() * sizeof(std::complex<int16_t>) << " bytes" << std::endl; > > // Get and print the maximum number of samples per packet > size_t max_num_samps = tx_stream->get_max_num_samps(); > std::cout << "Max number of samples per packet: " << max_num_samps << std::endl; > > // Initialize timestamp > md.time_spec = uhd::time_spec_t(usrp->get_time_now().get_full_secs() + 1.0); // Start 1 second in the future > > while (1 /*!stop_logging.load()*/) { > //if (gps_locked.load()) { > // md.time_spec = uhd::time_spec_t(usrp->get_time_now().get_full_secs() + 1.0); > //} > > size_t num_tx_samps = tx_stream->send(&buffer.front(), buffer.size(), md); > > if (num_tx_samps < buffer.size()) { > dropped_packets++; > } else { > transmitted_packets++; > } > > md.time_spec = md.time_spec + uhd::time_spec_t(buffer.size() / rate); > > md.start_of_burst = false; > //std::this_thread::sleep_for(std::chrono::milliseconds(5)); > } > > // Mark end of burst > md.end_of_burst = true; > tx_stream->send("", 0, md); > } > > // Second Test Program 2) > void transmit_packets_no_timespec(uhd::usrp::multi_usrp::sptr usrp, uhd::tx_streamer::sptr tx_stream, std::atomic<bool> &gps_locked, double rate) { > uhd::tx_metadata_t md; > md.start_of_burst = true; > md.end_of_burst = false; > md.has_time_spec = false; // No time specification > > std::vector<std::complex<int16_t>> buffer(2048); > > std::cout << "Start transmit_packets_no_timespec()" << std::endl; > std::cout << "Packet size: " << buffer.size() * sizeof(std::complex<int16_t>) << " bytes" << std::endl; > > while (!stop_logging.load()) { > size_t num_tx_samps = tx_stream->send(&buffer.front(), buffer.size(), md); > > if (num_tx_samps < buffer.size()) { > dropped_packets++; > } else { > transmitted_packets++; > } > > md.start_of_burst = false; > // Adjust the sleep time to control the packet rate > // std::this_thread::sleep_for(std::chrono::milliseconds(1)); > } > > // Mark end of burst > md.end_of_burst = true; > tx_stream->send("", 0, md); > } > > _______________________________________________ > USRP-users mailing list -- usrp-users@lists.ettus.com > To unsubscribe send an email to usrp-users-leave@lists.ettus.com >
C
cjohnson@serranosystems.com
Tue, Jun 25, 2024 1:17 AM

Hi Wade,

I am now receiving “U” instead of “L”.  They don’t come out on the console that often, but it is “bad” if I see any.
In addition, I did add a priority to the thread, you can see below (takes on a value between 0.0-100.0).
I also tried setting the buffer to 10*1996.
None of these efforts helped.
Any suggestions on how I can get this to work without losing packets, or timing?  FYI usrp->set_tx_rate(200e6).
(Below is code, below that is the console output)

// Main function to simulate packet transmission
void transmit_packets_timespec(uhd::usrp::multi_usrp::sptr usrp, uhd::tx_streamer::sptr tx_stream, std::atomic<bool> &gps_locked, double rate) {
    uhd::tx_metadata_t md;
    md.start_of_burst = true;
    md.end_of_burst = false;
    md.has_time_spec = true;

    // Attempt to set the thread priority
    bool success = uhd::set_thread_priority_safe(0.90, true);
    if (success) {
        std::cout << "uhd::set_thread_priority_safe::Thread priority successfully set." << std::endl;
    } else {
        std::cout << "uhd::set_thread_priority_safe::Failed to set thread priority." << std::endl;
    }

    std::vector<std::complex<int16_t>> buffer(1996); 

    std::cout << "Start transmit_packets_timespec()" << std::endl;
    std::cout << "Packet size: " << buffer.size() * sizeof(std::complex<int16_t>) << " bytes" << std::endl;

    // Get and print the maximum number of samples per packet
    size_t max_num_samps = tx_stream->get_max_num_samps();
    std::cout << "Max number of samples per packet: " << max_num_samps << std::endl;

    // Initialize timestamp
    md.time_spec = uhd::time_spec_t(usrp->get_time_now().get_full_secs() + 1.0); // Start 1 second in the future

    while (true) {

        size_t num_tx_samps = tx_stream->send(&buffer.front(), buffer.size(), md);

        if (num_tx_samps < buffer.size()) {
            dropped_packets++;
        } else {
            transmitted_packets++;
        }

        //md.time_spec = md.time_spec + uhd::time_spec_t(buffer.size() / rate);
        md.has_time_spec = false;

        md.start_of_burst = false;
    }

    // Mark end of burst
    md.end_of_burst = true;
    tx_stream->send("", 0, md);
}

CONSOLE OUTPUT:

sudo ./tx_timed_samples_perf
[INFO] [UHD] linux; GNU C++ version 9.4.0; Boost_107100; UHD_4.6.0.0-1-ga9f0b4c7
[INFO] [X300] X300 initialization sequence...

[INFO] [X300] Maximum frame size: 8000 bytes.
[INFO] [GPS] Found an internal GPSDO: LC_XO, Firmware Rev 0.929a
[INFO] [X300] Radio 1x clock: 200 MHz
Actual TX Rate: 200.000000 Msps
Actual TX Freq: 1223.000003 MHz
Actual TX Gain: 20.000000 dB
Actual TX Bandwidth: 200.000000 MHz
[WARNING] [0/Radio#0] Attempting to set tick rate to 0. Skipping.
Using transmit_packets_timespec()
uhd::set_thread_priority_safe::Thread priority successfully set.
Start transmit_packets_timespec()
Packet size: 7984 bytes
Max number of samples per packet: 1996
UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU

Hi Wade, I am now receiving “U” instead of “L”. They don’t come out on the console that often, but it is “bad” if I see any.\ In addition, I did add a priority to the thread, you can see below (takes on a value between 0.0-100.0).\ I also tried setting the buffer to 10\*1996.\ None of these efforts helped.\ Any suggestions on how I can get this to work without losing packets, or timing? FYI usrp->set_tx_rate(200e6).\ (Below is code, below that is the console output) ``` // Main function to simulate packet transmission void transmit_packets_timespec(uhd::usrp::multi_usrp::sptr usrp, uhd::tx_streamer::sptr tx_stream, std::atomic<bool> &gps_locked, double rate) { uhd::tx_metadata_t md; md.start_of_burst = true; md.end_of_burst = false; md.has_time_spec = true; // Attempt to set the thread priority bool success = uhd::set_thread_priority_safe(0.90, true); if (success) { std::cout << "uhd::set_thread_priority_safe::Thread priority successfully set." << std::endl; } else { std::cout << "uhd::set_thread_priority_safe::Failed to set thread priority." << std::endl; } std::vector<std::complex<int16_t>> buffer(1996); std::cout << "Start transmit_packets_timespec()" << std::endl; std::cout << "Packet size: " << buffer.size() * sizeof(std::complex<int16_t>) << " bytes" << std::endl; // Get and print the maximum number of samples per packet size_t max_num_samps = tx_stream->get_max_num_samps(); std::cout << "Max number of samples per packet: " << max_num_samps << std::endl; // Initialize timestamp md.time_spec = uhd::time_spec_t(usrp->get_time_now().get_full_secs() + 1.0); // Start 1 second in the future while (true) { size_t num_tx_samps = tx_stream->send(&buffer.front(), buffer.size(), md); if (num_tx_samps < buffer.size()) { dropped_packets++; } else { transmitted_packets++; } //md.time_spec = md.time_spec + uhd::time_spec_t(buffer.size() / rate); md.has_time_spec = false; md.start_of_burst = false; } // Mark end of burst md.end_of_burst = true; tx_stream->send("", 0, md); } ``` **CONSOLE OUTPUT:** sudo ./tx_timed_samples_perf \[INFO\] \[UHD\] linux; GNU C++ version 9.4.0; Boost_107100; UHD_4.6.0.0-1-ga9f0b4c7 \[INFO\] \[X300\] X300 initialization sequence... \[INFO\] \[X300\] Maximum frame size: 8000 bytes. \[INFO\] \[GPS\] Found an internal GPSDO: LC_XO, Firmware Rev 0.929a \[INFO\] \[X300\] Radio 1x clock: 200 MHz Actual TX Rate: 200.000000 Msps Actual TX Freq: 1223.000003 MHz Actual TX Gain: 20.000000 dB Actual TX Bandwidth: 200.000000 MHz \[WARNING\] \[0/Radio#0\] Attempting to set tick rate to 0. Skipping. Using transmit_packets_timespec() uhd::set_thread_priority_safe::Thread priority successfully set. Start transmit_packets_timespec() Packet size: 7984 bytes Max number of samples per packet: 1996 UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU
WF
Wade Fife
Wed, Jun 26, 2024 3:43 AM

You might need to make some tweaks to your system. Take a look at the
suggestions here:
https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks

Wade

On Mon, Jun 24, 2024 at 8:18 PM cjohnson@serranosystems.com wrote:

Hi Wade,

I am now receiving “U” instead of “L”. They don’t come out on the console
that often, but it is “bad” if I see any.
In addition, I did add a priority to the thread, you can see below (takes
on a value between 0.0-100.0).
I also tried setting the buffer to 10*1996.
None of these efforts helped.
Any suggestions on how I can get this to work without losing packets, or
timing? FYI usrp->set_tx_rate(200e6).
(Below is code, below that is the console output)

// Main function to simulate packet transmission
void transmit_packets_timespec(uhd::usrp::multi_usrp::sptr usrp, uhd::tx_streamer::sptr tx_stream, std::atomic<bool> &gps_locked, double rate) {
uhd::tx_metadata_t md;
md.start_of_burst = true;
md.end_of_burst = false;
md.has_time_spec = true;

 // Attempt to set the thread priority
 bool success = uhd::set_thread_priority_safe(0.90, true);
 if (success) {
     std::cout << "uhd::set_thread_priority_safe::Thread priority successfully set." << std::endl;
 } else {
     std::cout << "uhd::set_thread_priority_safe::Failed to set thread priority." << std::endl;
 }

 std::vector<std::complex<int16_t>> buffer(1996);

 std::cout << "Start transmit_packets_timespec()" << std::endl;
 std::cout << "Packet size: " << buffer.size() * sizeof(std::complex<int16_t>) << " bytes" << std::endl;

 // Get and print the maximum number of samples per packet
 size_t max_num_samps = tx_stream->get_max_num_samps();
 std::cout << "Max number of samples per packet: " << max_num_samps << std::endl;

 // Initialize timestamp
 md.time_spec = uhd::time_spec_t(usrp->get_time_now().get_full_secs() + 1.0); // Start 1 second in the future

 while (true) {

     size_t num_tx_samps = tx_stream->send(&buffer.front(), buffer.size(), md);

     if (num_tx_samps < buffer.size()) {
         dropped_packets++;
     } else {
         transmitted_packets++;
     }

     //md.time_spec = md.time_spec + uhd::time_spec_t(buffer.size() / rate);
     md.has_time_spec = false;

     md.start_of_burst = false;
 }

 // Mark end of burst
 md.end_of_burst = true;
 tx_stream->send("", 0, md);

}

CONSOLE OUTPUT:

sudo ./tx_timed_samples_perf [INFO] [UHD] linux; GNU C++ version 9.4.0;
Boost_107100; UHD_4.6.0.0-1-ga9f0b4c7 [INFO] [X300] X300 initialization
sequence... [INFO] [X300] Maximum frame size: 8000 bytes. [INFO] [GPS]
Found an internal GPSDO: LC_XO, Firmware Rev 0.929a [INFO] [X300] Radio 1x
clock: 200 MHz Actual TX Rate: 200.000000 Msps Actual TX Freq: 1223.000003
MHz Actual TX Gain: 20.000000 dB Actual TX Bandwidth: 200.000000 MHz
[WARNING] [0/Radio#0] Attempting to set tick rate to 0. Skipping. Using
transmit_packets_timespec() uhd::set_thread_priority_safe::Thread priority
successfully set. Start transmit_packets_timespec() Packet size: 7984 bytes
Max number of samples per packet: 1996
UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU


USRP-users mailing list -- usrp-users@lists.ettus.com
To unsubscribe send an email to usrp-users-leave@lists.ettus.com

You might need to make some tweaks to your system. Take a look at the suggestions here: https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks Wade On Mon, Jun 24, 2024 at 8:18 PM <cjohnson@serranosystems.com> wrote: > Hi Wade, > > I am now receiving “U” instead of “L”. They don’t come out on the console > that often, but it is “bad” if I see any. > In addition, I did add a priority to the thread, you can see below (takes > on a value between 0.0-100.0). > I also tried setting the buffer to 10*1996. > None of these efforts helped. > Any suggestions on how I can get this to work without losing packets, or > timing? FYI usrp->set_tx_rate(200e6). > (Below is code, below that is the console output) > > // Main function to simulate packet transmission > void transmit_packets_timespec(uhd::usrp::multi_usrp::sptr usrp, uhd::tx_streamer::sptr tx_stream, std::atomic<bool> &gps_locked, double rate) { > uhd::tx_metadata_t md; > md.start_of_burst = true; > md.end_of_burst = false; > md.has_time_spec = true; > > // Attempt to set the thread priority > bool success = uhd::set_thread_priority_safe(0.90, true); > if (success) { > std::cout << "uhd::set_thread_priority_safe::Thread priority successfully set." << std::endl; > } else { > std::cout << "uhd::set_thread_priority_safe::Failed to set thread priority." << std::endl; > } > > std::vector<std::complex<int16_t>> buffer(1996); > > std::cout << "Start transmit_packets_timespec()" << std::endl; > std::cout << "Packet size: " << buffer.size() * sizeof(std::complex<int16_t>) << " bytes" << std::endl; > > // Get and print the maximum number of samples per packet > size_t max_num_samps = tx_stream->get_max_num_samps(); > std::cout << "Max number of samples per packet: " << max_num_samps << std::endl; > > // Initialize timestamp > md.time_spec = uhd::time_spec_t(usrp->get_time_now().get_full_secs() + 1.0); // Start 1 second in the future > > while (true) { > > size_t num_tx_samps = tx_stream->send(&buffer.front(), buffer.size(), md); > > if (num_tx_samps < buffer.size()) { > dropped_packets++; > } else { > transmitted_packets++; > } > > //md.time_spec = md.time_spec + uhd::time_spec_t(buffer.size() / rate); > md.has_time_spec = false; > > md.start_of_burst = false; > } > > // Mark end of burst > md.end_of_burst = true; > tx_stream->send("", 0, md); > } > > *CONSOLE OUTPUT:* > > sudo ./tx_timed_samples_perf [INFO] [UHD] linux; GNU C++ version 9.4.0; > Boost_107100; UHD_4.6.0.0-1-ga9f0b4c7 [INFO] [X300] X300 initialization > sequence... [INFO] [X300] Maximum frame size: 8000 bytes. [INFO] [GPS] > Found an internal GPSDO: LC_XO, Firmware Rev 0.929a [INFO] [X300] Radio 1x > clock: 200 MHz Actual TX Rate: 200.000000 Msps Actual TX Freq: 1223.000003 > MHz Actual TX Gain: 20.000000 dB Actual TX Bandwidth: 200.000000 MHz > [WARNING] [0/Radio#0] Attempting to set tick rate to 0. Skipping. Using > transmit_packets_timespec() uhd::set_thread_priority_safe::Thread priority > successfully set. Start transmit_packets_timespec() Packet size: 7984 bytes > Max number of samples per packet: 1996 > UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU > _______________________________________________ > USRP-users mailing list -- usrp-users@lists.ettus.com > To unsubscribe send an email to usrp-users-leave@lists.ettus.com >
C
cjohnson@serranosystems.com
Thu, Jun 27, 2024 2:48 AM

Hi,

I appreciate the response.  I previously made all of those changes (except bios, DPDK, and Sprectre).  In addition, I have MTU at 9000.  I just re-verified.

I’m still getting the U’s.

So we could have the same common code as a starting point, I modified your tx_timed_samples.cpp provided below so you can reproduce the problem.

Here are the changes:

  • Sends continuously (instead of some a set number of samples)

  • Data is sc16 and not fc32

  • Data rate is 200e6 SPS instead of a much lower value



//
// Copyright 2010-2011,2014 Ettus Research LLC
// Copyright 2018 Ettus Research, a National Instruments Company
//
// SPDX-License-Identifier: GPL-3.0-or-later
//

#include <uhd/usrp/multi_usrp.hpp>
#include <uhd/utils/safe_main.hpp>
#include <uhd/utils/thread.hpp>
#include <boost/format.hpp>
#include <boost/program_options.hpp>
#include <boost/thread/thread.hpp>
#include <complex>
#include <iostream>

namespace po = boost::program_options;

int UHD_SAFE_MAIN(int argc, char* argv[])
{
    // variables to be set by po
    std::string args;
    std::string wire;
    double seconds_in_future;
    size_t total_num_samps;
    double rate;
    float ampl;

    // setup the program options
    po::options_description desc("Allowed options");
    // clang-format off
    desc.add_options()
        ("help", "help message")
//        ("args", po::value<std::string>(&args)->default_value(""), "single uhd device address args")
        ("args", po::value<std::string>(&args)->default_value("type=x300,addr=192.168.40.2"), "single uhd device address args")
        ("wire", po::value<std::string>(&wire)->default_value(""), "the over the wire type, sc16, sc8, etc")
        ("secs", po::value<double>(&seconds_in_future)->default_value(1.5), "number of seconds in the future to transmit")
        ("nsamps", po::value<size_t>(&total_num_samps)->default_value(10000), "total number of samples to transmit")
//        ("rate", po::value<double>(&rate)->default_value(100e6/16), "rate of outgoing samples")
        ("rate", po::value<double>(&rate)->default_value(200e6), "rate of outgoing samples")
        ("ampl", po::value<float>(&ampl)->default_value(float(0.3)), "amplitude of each sample")
        ("dilv", "specify to disable inner-loop verbose")
    ;
    // clang-format on
    po::variables_map vm;
    po::store(po::parse_command_line(argc, argv, desc), vm);
    po::notify(vm);

    // print the help message
    if (vm.count("help")) {
        std::cout << boost::format("UHD TX Timed Samples %s") % desc << std::endl;
        return ~0;
    }

    bool verbose = vm.count("dilv") == 0;

    // create a usrp device
    std::cout << std::endl;
    std::cout << boost::format("Creating the usrp device with: %s...") % args
              << std::endl;
    uhd::usrp::multi_usrp::sptr usrp = uhd::usrp::multi_usrp::make(args);
    std::cout << boost::format("Using Device: %s") % usrp->get_pp_string() << std::endl;

    // set the tx sample rate
    std::cout << boost::format("Setting TX Rate: %f Msps...") % (rate / 1e6) << std::endl;
    usrp->set_tx_rate(rate);
    std::cout << boost::format("Actual TX Rate: %f Msps...") % (usrp->get_tx_rate() / 1e6)
              << std::endl
              << std::endl;

    std::cout << boost::format("Setting device timestamp to 0...") << std::endl;
    usrp->set_time_now(uhd::time_spec_t(0.0));

    // create a transmit streamer
//    uhd::stream_args_t stream_args("fc32", wire); // complex floats
    uhd::stream_args_t stream_args("sc16", "sc16");
    uhd::tx_streamer::sptr tx_stream = usrp->get_tx_stream(stream_args);

    // allocate buffer with data to send
//    std::vector<std::complex<float>> buff(tx_stream->get_max_num_samps(), std::complex<float>(ampl, ampl));
    typedef uint16_t sample_t;    // Either the I or Q portion of an IQ sample.
    std::vector<std::complex<sample_t>> buff(tx_stream->get_max_num_samps(), std::complex<sample_t>(ampl * 32767, ampl * 32767));

    // setup metadata for the first packet
    uhd::tx_metadata_t md;
    md.start_of_burst = false;
    md.end_of_burst   = false;
    md.has_time_spec  = true;
    md.time_spec      = uhd::time_spec_t(seconds_in_future);

    // the first call to send() will block this many seconds before sending:
    const double timeout =
        seconds_in_future + 0.1; // timeout (delay before transmit + padding)

#if 1
    while (true) {
        size_t num_tx_samps = tx_stream->send(&buff.front(), buff.size(), md);

        if (num_tx_samps < buff.size()) {
            std::cerr << "Send timeout..." << std::endl;
        }

        // do not use time spec for subsequent packets
        md.has_time_spec = false;
    }
#else
    size_t num_acc_samps = 0; // number of accumulated samples
    while (num_acc_samps < total_num_samps) {
        size_t samps_to_send = std::min(total_num_samps - num_acc_samps, buff.size());

        // send a single packet
        size_t num_tx_samps = tx_stream->send(&buff.front(), samps_to_send, md, timeout);

        // do not use time spec for subsequent packets
        md.has_time_spec = false;

        if (num_tx_samps < samps_to_send)
            std::cerr << "Send timeout..." << std::endl;
        if (verbose)
            std::cout << boost::format("Sent packet: %u samples") % num_tx_samps
                      << std::endl;

        num_acc_samps += num_tx_samps;
    }
#endif

    // send a mini EOB packet
    md.end_of_burst = true;
    tx_stream->send("", 0, md);

    std::cout << std::endl << "Waiting for async burst ACK... " << std::flush;
    uhd::async_metadata_t async_md;
    bool got_async_burst_ack = false;
    // loop through all messages for the ACK packet (may have underflow messages in queue)
    while (not got_async_burst_ack and tx_stream->recv_async_msg(async_md, timeout)) {
        got_async_burst_ack =
            (async_md.event_code == uhd::async_metadata_t::EVENT_CODE_BURST_ACK);
    }
    std::cout << (got_async_burst_ack ? "success" : "fail") << std::endl;

    // finished
    std::cout << std::endl << "Done!" << std::endl << std::endl;

    return EXIT_SUCCESS;
}
Hi, I appreciate the response. I previously made all of those changes (except bios, DPDK, and Sprectre). In addition, I have MTU at 9000. I just re-verified. I’m still getting the U’s. So we could have the same common code as a starting point, I modified your tx_timed_samples.cpp provided below so you can reproduce the problem. Here are the changes: * Sends continuously (instead of some a set number of samples) * Data is sc16 and not fc32 * Data rate is 200e6 SPS instead of a much lower value ``` // // Copyright 2010-2011,2014 Ettus Research LLC // Copyright 2018 Ettus Research, a National Instruments Company // // SPDX-License-Identifier: GPL-3.0-or-later // #include <uhd/usrp/multi_usrp.hpp> #include <uhd/utils/safe_main.hpp> #include <uhd/utils/thread.hpp> #include <boost/format.hpp> #include <boost/program_options.hpp> #include <boost/thread/thread.hpp> #include <complex> #include <iostream> namespace po = boost::program_options; int UHD_SAFE_MAIN(int argc, char* argv[]) { // variables to be set by po std::string args; std::string wire; double seconds_in_future; size_t total_num_samps; double rate; float ampl; // setup the program options po::options_description desc("Allowed options"); // clang-format off desc.add_options() ("help", "help message") // ("args", po::value<std::string>(&args)->default_value(""), "single uhd device address args") ("args", po::value<std::string>(&args)->default_value("type=x300,addr=192.168.40.2"), "single uhd device address args") ("wire", po::value<std::string>(&wire)->default_value(""), "the over the wire type, sc16, sc8, etc") ("secs", po::value<double>(&seconds_in_future)->default_value(1.5), "number of seconds in the future to transmit") ("nsamps", po::value<size_t>(&total_num_samps)->default_value(10000), "total number of samples to transmit") // ("rate", po::value<double>(&rate)->default_value(100e6/16), "rate of outgoing samples") ("rate", po::value<double>(&rate)->default_value(200e6), "rate of outgoing samples") ("ampl", po::value<float>(&ampl)->default_value(float(0.3)), "amplitude of each sample") ("dilv", "specify to disable inner-loop verbose") ; // clang-format on po::variables_map vm; po::store(po::parse_command_line(argc, argv, desc), vm); po::notify(vm); // print the help message if (vm.count("help")) { std::cout << boost::format("UHD TX Timed Samples %s") % desc << std::endl; return ~0; } bool verbose = vm.count("dilv") == 0; // create a usrp device std::cout << std::endl; std::cout << boost::format("Creating the usrp device with: %s...") % args << std::endl; uhd::usrp::multi_usrp::sptr usrp = uhd::usrp::multi_usrp::make(args); std::cout << boost::format("Using Device: %s") % usrp->get_pp_string() << std::endl; // set the tx sample rate std::cout << boost::format("Setting TX Rate: %f Msps...") % (rate / 1e6) << std::endl; usrp->set_tx_rate(rate); std::cout << boost::format("Actual TX Rate: %f Msps...") % (usrp->get_tx_rate() / 1e6) << std::endl << std::endl; std::cout << boost::format("Setting device timestamp to 0...") << std::endl; usrp->set_time_now(uhd::time_spec_t(0.0)); // create a transmit streamer // uhd::stream_args_t stream_args("fc32", wire); // complex floats uhd::stream_args_t stream_args("sc16", "sc16"); uhd::tx_streamer::sptr tx_stream = usrp->get_tx_stream(stream_args); // allocate buffer with data to send // std::vector<std::complex<float>> buff(tx_stream->get_max_num_samps(), std::complex<float>(ampl, ampl)); typedef uint16_t sample_t; // Either the I or Q portion of an IQ sample. std::vector<std::complex<sample_t>> buff(tx_stream->get_max_num_samps(), std::complex<sample_t>(ampl * 32767, ampl * 32767)); // setup metadata for the first packet uhd::tx_metadata_t md; md.start_of_burst = false; md.end_of_burst = false; md.has_time_spec = true; md.time_spec = uhd::time_spec_t(seconds_in_future); // the first call to send() will block this many seconds before sending: const double timeout = seconds_in_future + 0.1; // timeout (delay before transmit + padding) #if 1 while (true) { size_t num_tx_samps = tx_stream->send(&buff.front(), buff.size(), md); if (num_tx_samps < buff.size()) { std::cerr << "Send timeout..." << std::endl; } // do not use time spec for subsequent packets md.has_time_spec = false; } #else size_t num_acc_samps = 0; // number of accumulated samples while (num_acc_samps < total_num_samps) { size_t samps_to_send = std::min(total_num_samps - num_acc_samps, buff.size()); // send a single packet size_t num_tx_samps = tx_stream->send(&buff.front(), samps_to_send, md, timeout); // do not use time spec for subsequent packets md.has_time_spec = false; if (num_tx_samps < samps_to_send) std::cerr << "Send timeout..." << std::endl; if (verbose) std::cout << boost::format("Sent packet: %u samples") % num_tx_samps << std::endl; num_acc_samps += num_tx_samps; } #endif // send a mini EOB packet md.end_of_burst = true; tx_stream->send("", 0, md); std::cout << std::endl << "Waiting for async burst ACK... " << std::flush; uhd::async_metadata_t async_md; bool got_async_burst_ack = false; // loop through all messages for the ACK packet (may have underflow messages in queue) while (not got_async_burst_ack and tx_stream->recv_async_msg(async_md, timeout)) { got_async_burst_ack = (async_md.event_code == uhd::async_metadata_t::EVENT_CODE_BURST_ACK); } std::cout << (got_async_burst_ack ? "success" : "fail") << std::endl; // finished std::cout << std::endl << "Done!" << std::endl << std::endl; return EXIT_SUCCESS; } ```
MD
Marcus D. Leech
Thu, Jun 27, 2024 3:13 AM

On 26/06/2024 22:48, cjohnson@serranosystems.com wrote:

Hi,

I appreciate the response. I previously made all of those changes
(except bios, DPDK, and Sprectre). In addition, I have MTU at 9000. I
just re-verified.

I don't think the 2974 SOM embedded computer has the type of interface
that would be supported by DPDK, but I could
  be wrong.

I’m still getting the U’s.

I think the basic problem is that 4-core i7 on that board is now a
9-year-old design, and maxes out at 2.8GHz clock
  frequency, and it just doesn't have enough grunt to sustain 200e6 SPS.

I think the MTU issue is a red-herring.   The packet-overhead difference
between 9000 and 8000 MTU is very small
  (about 0.1% using a rough number of 40 bytes of packet overhead).  
The interrupt-load difference would be
  about 12.5%, except that would be a naive over-estimate given that
the 10Gig NIC subsystem almost certainly
  does a lot of interrupt aggregation, etc.

So we could have the same common code as a starting point, I modified
your tx_timed_samples.cpp provided below so you can reproduce the problem.

Here are the changes:

 Sends continuously (instead of some a set number of samples)
 Data is sc16 and not fc32
 Data rate is 200e6 SPS instead of a much lower value

|// // Copyright 2010-2011,2014 Ettus Research LLC // Copyright 2018
Ettus Research, a National Instruments Company // //
SPDX-License-Identifier: GPL-3.0-or-later // #include
<uhd/usrp/multi_usrp.hpp> #include <uhd/utils/safe_main.hpp> #include
<uhd/utils/thread.hpp> #include <boost/format.hpp> #include
<boost/program_options.hpp> #include <boost/thread/thread.hpp>
#include <complex> #include <iostream> namespace po =
boost::program_options; int UHD_SAFE_MAIN(int argc, char* argv[]) { //
variables to be set by po std::string args; std::string wire; double
seconds_in_future; size_t total_num_samps; double rate; float ampl; //
setup the program options po::options_description desc("Allowed
options"); // clang-format off desc.add_options() ("help", "help
message") // ("args",
po::valuestd::string(&args)->default_value(""), "single uhd device
address args") ("args",
po::valuestd::string(&args)->default_value("type=x300,addr=192.168.40.2"),
"single uhd device address args") ("wire",
po::valuestd::string(&wire)->default_value(""), "the over the wire
type, sc16, sc8, etc") ("secs",
po::value<double>(&seconds_in_future)->default_value(1.5), "number of
seconds in the future to transmit") ("nsamps",
po::value<size_t>(&total_num_samps)->default_value(10000), "total
number of samples to transmit") // ("rate",
po::value<double>(&rate)->default_value(100e6/16), "rate of outgoing
samples") ("rate", po::value<double>(&rate)->default_value(200e6),
"rate of outgoing samples") ("ampl",
po::value<float>(&ampl)->default_value(float(0.3)), "amplitude of each
sample") ("dilv", "specify to disable inner-loop verbose") ; //
clang-format on po::variables_map vm;
po::store(po::parse_command_line(argc, argv, desc), vm);
po::notify(vm); // print the help message if (vm.count("help")) {
std::cout << boost::format("UHD TX Timed Samples %s") % desc <<
std::endl; return ~0; } bool verbose = vm.count("dilv") == 0; //
create a usrp device std::cout << std::endl; std::cout <<
boost::format("Creating the usrp device with: %s...") % args <<
std::endl; uhd::usrp::multi_usrp::sptr usrp =
uhd::usrp::multi_usrp::make(args); std::cout << boost::format("Using
Device: %s") % usrp->get_pp_string() << std::endl; // set the tx
sample rate std::cout << boost::format("Setting TX Rate: %f Msps...")
% (rate / 1e6) << std::endl; usrp->set_tx_rate(rate); std::cout <<
boost::format("Actual TX Rate: %f Msps...") % (usrp->get_tx_rate() /
1e6) << std::endl << std::endl; std::cout << boost::format("Setting
device timestamp to 0...") << std::endl;
usrp->set_time_now(uhd::time_spec_t(0.0)); // create a transmit
streamer // uhd::stream_args_t stream_args("fc32", wire); // complex
floats uhd::stream_args_t stream_args("sc16", "sc16");
uhd::tx_streamer::sptr tx_stream = usrp->get_tx_stream(stream_args);
// allocate buffer with data to send //
std::vector<std::complex<float>> buff(tx_stream->get_max_num_samps(),
std::complex<float>(ampl, ampl)); typedef uint16_t sample_t; // Either
the I or Q portion of an IQ sample.
std::vector<std::complex<sample_t>>
buff(tx_stream->get_max_num_samps(), std::complex<sample_t>(ampl *
32767, ampl * 32767)); // setup metadata for the first packet
uhd::tx_metadata_t md; md.start_of_burst = false; md.end_of_burst =
false; md.has_time_spec = true; md.time_spec =
uhd::time_spec_t(seconds_in_future); // the first call to send() will
block this many seconds before sending: const double timeout =
seconds_in_future + 0.1; // timeout (delay before transmit + padding)
#if 1 while (true) { size_t num_tx_samps =
tx_stream->send(&buff.front(), buff.size(), md); if (num_tx_samps <
buff.size()) { std::cerr << "Send timeout..." << std::endl; } // do
not use time spec for subsequent packets md.has_time_spec = false; }
#else size_t num_acc_samps = 0; // number of accumulated samples while
(num_acc_samps < total_num_samps) { size_t samps_to_send =
std::min(total_num_samps - num_acc_samps, buff.size()); // send a
single packet size_t num_tx_samps = tx_stream->send(&buff.front(),
samps_to_send, md, timeout); // do not use time spec for subsequent
packets md.has_time_spec = false; if (num_tx_samps < samps_to_send)
std::cerr << "Send timeout..." << std::endl; if (verbose) std::cout <<
boost::format("Sent packet: %u samples") % num_tx_samps << std::endl;
num_acc_samps += num_tx_samps; } #endif // send a mini EOB packet
md.end_of_burst = true; tx_stream->send("", 0, md); std::cout <<
std::endl << "Waiting for async burst ACK... " << std::flush;
uhd::async_metadata_t async_md; bool got_async_burst_ack = false; //
loop through all messages for the ACK packet (may have underflow
messages in queue) while (not got_async_burst_ack and
tx_stream->recv_async_msg(async_md, timeout)) { got_async_burst_ack =
(async_md.event_code == uhd::async_metadata_t::EVENT_CODE_BURST_ACK);
} std::cout << (got_async_burst_ack ? "success" : "fail") <<
std::endl; // finished std::cout << std::endl << "Done!" << std::endl
<< std::endl; return EXIT_SUCCESS; } |


USRP-users mailing list --usrp-users@lists.ettus.com
To unsubscribe send an email tousrp-users-leave@lists.ettus.com

On 26/06/2024 22:48, cjohnson@serranosystems.com wrote: > > Hi, > > I appreciate the response. I previously made all of those changes > (except bios, DPDK, and Sprectre). In addition, I have MTU at 9000. I > just re-verified. > I don't *think* the 2974 SOM embedded computer has the type of interface that would be supported by DPDK, but I could   be wrong. > I’m still getting the U’s. > I think the basic problem is that 4-core i7 on that board is now a 9-year-old design, and maxes out at 2.8GHz clock   frequency, and it just doesn't have enough grunt to sustain 200e6 SPS. I think the MTU issue is a red-herring.   The packet-overhead difference between 9000 and 8000 MTU is very small   (about 0.1% using a rough number of 40 bytes of packet overhead).   The interrupt-load difference would be   about 12.5%, except that would be a naive over-estimate given that the 10Gig NIC subsystem almost certainly   does a lot of interrupt aggregation, etc. > So we could have the same common code as a starting point, I modified > your tx_timed_samples.cpp provided below so you can reproduce the problem. > > Here are the changes: > > * > > Sends continuously (instead of some a set number of samples) > > * > > Data is sc16 and not fc32 > > * > > Data rate is 200e6 SPS instead of a much lower value > > |// // Copyright 2010-2011,2014 Ettus Research LLC // Copyright 2018 > Ettus Research, a National Instruments Company // // > SPDX-License-Identifier: GPL-3.0-or-later // #include > <uhd/usrp/multi_usrp.hpp> #include <uhd/utils/safe_main.hpp> #include > <uhd/utils/thread.hpp> #include <boost/format.hpp> #include > <boost/program_options.hpp> #include <boost/thread/thread.hpp> > #include <complex> #include <iostream> namespace po = > boost::program_options; int UHD_SAFE_MAIN(int argc, char* argv[]) { // > variables to be set by po std::string args; std::string wire; double > seconds_in_future; size_t total_num_samps; double rate; float ampl; // > setup the program options po::options_description desc("Allowed > options"); // clang-format off desc.add_options() ("help", "help > message") // ("args", > po::value<std::string>(&args)->default_value(""), "single uhd device > address args") ("args", > po::value<std::string>(&args)->default_value("type=x300,addr=192.168.40.2"), > "single uhd device address args") ("wire", > po::value<std::string>(&wire)->default_value(""), "the over the wire > type, sc16, sc8, etc") ("secs", > po::value<double>(&seconds_in_future)->default_value(1.5), "number of > seconds in the future to transmit") ("nsamps", > po::value<size_t>(&total_num_samps)->default_value(10000), "total > number of samples to transmit") // ("rate", > po::value<double>(&rate)->default_value(100e6/16), "rate of outgoing > samples") ("rate", po::value<double>(&rate)->default_value(200e6), > "rate of outgoing samples") ("ampl", > po::value<float>(&ampl)->default_value(float(0.3)), "amplitude of each > sample") ("dilv", "specify to disable inner-loop verbose") ; // > clang-format on po::variables_map vm; > po::store(po::parse_command_line(argc, argv, desc), vm); > po::notify(vm); // print the help message if (vm.count("help")) { > std::cout << boost::format("UHD TX Timed Samples %s") % desc << > std::endl; return ~0; } bool verbose = vm.count("dilv") == 0; // > create a usrp device std::cout << std::endl; std::cout << > boost::format("Creating the usrp device with: %s...") % args << > std::endl; uhd::usrp::multi_usrp::sptr usrp = > uhd::usrp::multi_usrp::make(args); std::cout << boost::format("Using > Device: %s") % usrp->get_pp_string() << std::endl; // set the tx > sample rate std::cout << boost::format("Setting TX Rate: %f Msps...") > % (rate / 1e6) << std::endl; usrp->set_tx_rate(rate); std::cout << > boost::format("Actual TX Rate: %f Msps...") % (usrp->get_tx_rate() / > 1e6) << std::endl << std::endl; std::cout << boost::format("Setting > device timestamp to 0...") << std::endl; > usrp->set_time_now(uhd::time_spec_t(0.0)); // create a transmit > streamer // uhd::stream_args_t stream_args("fc32", wire); // complex > floats uhd::stream_args_t stream_args("sc16", "sc16"); > uhd::tx_streamer::sptr tx_stream = usrp->get_tx_stream(stream_args); > // allocate buffer with data to send // > std::vector<std::complex<float>> buff(tx_stream->get_max_num_samps(), > std::complex<float>(ampl, ampl)); typedef uint16_t sample_t; // Either > the I or Q portion of an IQ sample. > std::vector<std::complex<sample_t>> > buff(tx_stream->get_max_num_samps(), std::complex<sample_t>(ampl * > 32767, ampl * 32767)); // setup metadata for the first packet > uhd::tx_metadata_t md; md.start_of_burst = false; md.end_of_burst = > false; md.has_time_spec = true; md.time_spec = > uhd::time_spec_t(seconds_in_future); // the first call to send() will > block this many seconds before sending: const double timeout = > seconds_in_future + 0.1; // timeout (delay before transmit + padding) > #if 1 while (true) { size_t num_tx_samps = > tx_stream->send(&buff.front(), buff.size(), md); if (num_tx_samps < > buff.size()) { std::cerr << "Send timeout..." << std::endl; } // do > not use time spec for subsequent packets md.has_time_spec = false; } > #else size_t num_acc_samps = 0; // number of accumulated samples while > (num_acc_samps < total_num_samps) { size_t samps_to_send = > std::min(total_num_samps - num_acc_samps, buff.size()); // send a > single packet size_t num_tx_samps = tx_stream->send(&buff.front(), > samps_to_send, md, timeout); // do not use time spec for subsequent > packets md.has_time_spec = false; if (num_tx_samps < samps_to_send) > std::cerr << "Send timeout..." << std::endl; if (verbose) std::cout << > boost::format("Sent packet: %u samples") % num_tx_samps << std::endl; > num_acc_samps += num_tx_samps; } #endif // send a mini EOB packet > md.end_of_burst = true; tx_stream->send("", 0, md); std::cout << > std::endl << "Waiting for async burst ACK... " << std::flush; > uhd::async_metadata_t async_md; bool got_async_burst_ack = false; // > loop through all messages for the ACK packet (may have underflow > messages in queue) while (not got_async_burst_ack and > tx_stream->recv_async_msg(async_md, timeout)) { got_async_burst_ack = > (async_md.event_code == uhd::async_metadata_t::EVENT_CODE_BURST_ACK); > } std::cout << (got_async_burst_ack ? "success" : "fail") << > std::endl; // finished std::cout << std::endl << "Done!" << std::endl > << std::endl; return EXIT_SUCCESS; } | > > _______________________________________________ > USRP-users mailing list --usrp-users@lists.ettus.com > To unsubscribe send an email tousrp-users-leave@lists.ettus.com
C
cjohnson@serranosystems.com
Thu, Jun 27, 2024 7:41 PM

Hi,

Can you help me figure out what the problem is using the modified example (I provided in last response), a fast machine which has the tips and tricks implemented?

I directly connected our 64 core / 4 GPU / >250GI RAM workstation with 10G output directly to the X310 10G, which should easily keep up with 200Msps.

I ran the same program I provided above (I just modified your example program tx_timed_samples.cpp) and now it outputs S’s instead of U’s.

Here is the output:

cjohnson@demo:~/uhd_versions/uhd_4.4.0.0/host/build/examples$ ./tx_timed_samples

Creating the usrp device with: type=x300,addr=192.168.30.2...
[INFO] [UHD] linux; GNU C++ version 11.4.0; Boost_107400; UHD_4.4.0.HEAD-0-g5fac246b
[INFO] [X300] X300 initialization sequence...
[INFO] [X300] Maximum frame size: 8000 bytes.
[INFO] [GPS] Found an internal GPSDO: LC_XO, Firmware Rev 0.929a
[INFO] [X300] Radio 1x clock: 200 MHz
Using Device: Single USRP:
  Device: X-Series Device
  Mboard 0: X310
  RX Channel: 0
    RX DSP: 0
    RX Dboard: A
    RX Subdev: UBX RX
  RX Channel: 1
    RX DSP: 1
    RX Dboard: B
    RX Subdev: UBX RX
  TX Channel: 0
    TX DSP: 0
    TX Dboard: A
    TX Subdev: UBX TX
  TX Channel: 1
    TX DSP: 1
    TX Dboard: B
    TX Subdev: UBX TX

Setting TX Rate: 200.000000 Msps...
Actual TX Rate: 200.000000 Msps...

Setting device timestamp to 0...
[WARNING] [0/Radio#0] Attempting to set tick rate to 0. Skipping.
Send timeout...
Send timeout...
Send timeout...
Send timeout...
Send timeout...
Send timeout...
Send timeout...
SSSSSSSS (... more S's)

I verified the interface is setup for 9000 MTU, and that I have made the adjustments indicated in https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks
except for Specture / bios changes).  This includes Ring Buffers for NIC and Network Buffers

(Below, same for CPU 0-63)
analyzing CPU 63:
  driver: intel_cpufreq
  CPUs which run at the same hardware frequency: 63
  CPUs which need to have their frequency coordinated by software: 63
  maximum transition latency: 20.0 us.
  hardware limits: 800 MHz - 3.50 GHz
  available cpufreq governors: conservative, ondemand, userspace, powersave, performance, schedutil
  current policy: frequency should be within 800 MHz and 3.50 GHz.
                  The governor "performance" may decide which speed to use
                  within this range.
  current CPU frequency is 3.50 GHz.
Hi, Can you help me figure out what the problem is using the modified example (I provided in last response), a fast machine which has the tips and tricks implemented? I directly connected our 64 core / 4 GPU / >250GI RAM workstation with 10G output directly to the X310 10G, which should easily keep up with 200Msps. I ran the same program I provided above (I just modified your example program tx_timed_samples.cpp) and now it outputs S’s instead of U’s. Here is the output: ``` cjohnson@demo:~/uhd_versions/uhd_4.4.0.0/host/build/examples$ ./tx_timed_samples Creating the usrp device with: type=x300,addr=192.168.30.2... [INFO] [UHD] linux; GNU C++ version 11.4.0; Boost_107400; UHD_4.4.0.HEAD-0-g5fac246b [INFO] [X300] X300 initialization sequence... [INFO] [X300] Maximum frame size: 8000 bytes. [INFO] [GPS] Found an internal GPSDO: LC_XO, Firmware Rev 0.929a [INFO] [X300] Radio 1x clock: 200 MHz Using Device: Single USRP: Device: X-Series Device Mboard 0: X310 RX Channel: 0 RX DSP: 0 RX Dboard: A RX Subdev: UBX RX RX Channel: 1 RX DSP: 1 RX Dboard: B RX Subdev: UBX RX TX Channel: 0 TX DSP: 0 TX Dboard: A TX Subdev: UBX TX TX Channel: 1 TX DSP: 1 TX Dboard: B TX Subdev: UBX TX Setting TX Rate: 200.000000 Msps... Actual TX Rate: 200.000000 Msps... Setting device timestamp to 0... [WARNING] [0/Radio#0] Attempting to set tick rate to 0. Skipping. Send timeout... Send timeout... Send timeout... Send timeout... Send timeout... Send timeout... Send timeout... SSSSSSSS (... more S's) ``` I verified the interface is setup for 9000 MTU, and that I have made the adjustments indicated in <https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks>\ except for Specture / bios changes). This includes Ring Buffers for NIC and Network Buffers ``` (Below, same for CPU 0-63) analyzing CPU 63: driver: intel_cpufreq CPUs which run at the same hardware frequency: 63 CPUs which need to have their frequency coordinated by software: 63 maximum transition latency: 20.0 us. hardware limits: 800 MHz - 3.50 GHz available cpufreq governors: conservative, ondemand, userspace, powersave, performance, schedutil current policy: frequency should be within 800 MHz and 3.50 GHz. The governor "performance" may decide which speed to use within this range. current CPU frequency is 3.50 GHz. ```
MD
Marcus D. Leech
Thu, Jun 27, 2024 8:45 PM

On 27/06/2024 15:41, cjohnson@serranosystems.com wrote:

Hi,

Can you help me figure out what the problem is using the modified
example (I provided in last response), a fast machine which has the
tips and tricks implemented?

I directly connected our 64 core / 4 GPU / >250GI RAM workstation with
10G output directly to the X310 10G, which should easily keep up with
200Msps.

I ran the same program I provided above (I just modified your example
program tx_timed_samples.cpp) and now it outputs S’s instead of U’s.

Here is the output:

|cjohnson@demo:~/uhd_versions/uhd_4.4.0.0/host/build/examples$
./tx_timed_samples Creating the usrp device with:
type=x300,addr=192.168.30.2... [INFO] [UHD] linux; GNU C++ version
11.4.0; Boost_107400; UHD_4.4.0.HEAD-0-g5fac246b [INFO] [X300] X300
initialization sequence... [INFO] [X300] Maximum frame size: 8000
bytes. [INFO] [GPS] Found an internal GPSDO: LC_XO, Firmware Rev
0.929a [INFO] [X300] Radio 1x clock: 200 MHz Using Device: Single
USRP: Device: X-Series Device Mboard 0: X310 RX Channel: 0 RX DSP: 0
RX Dboard: A RX Subdev: UBX RX RX Channel: 1 RX DSP: 1 RX Dboard: B RX
Subdev: UBX RX TX Channel: 0 TX DSP: 0 TX Dboard: A TX Subdev: UBX TX
TX Channel: 1 TX DSP: 1 TX Dboard: B TX Subdev: UBX TX Setting TX
Rate: 200.000000 Msps... Actual TX Rate: 200.000000 Msps... Setting
device timestamp to 0... [WARNING] [0/Radio#0] Attempting to set tick
rate to 0. Skipping. Send timeout... Send timeout... Send timeout...
Send timeout... Send timeout... Send timeout... Send timeout...
SSSSSSSS (... more S's)|

I verified the interface is setup for 9000 MTU, and that I have made
the adjustments indicated in
https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks
except for Specture / bios changes). This includes Ring Buffers for
NIC and Network Buffers

|(Below, same for CPU 0-63) analyzing CPU 63: driver: intel_cpufreq
CPUs which run at the same hardware frequency: 63 CPUs which need to
have their frequency coordinated by software: 63 maximum transition
latency: 20.0 us. hardware limits: 800 MHz - 3.50 GHz available
cpufreq governors: conservative, ondemand, userspace, powersave,
performance, schedutil current policy: frequency should be within 800
MHz and 3.50 GHz. The governor "performance" may decide which speed to
use within this range. current CPU frequency is 3.50 GHz.|


USRP-users mailing list --usrp-users@lists.ettus.com
To unsubscribe send an email tousrp-users-leave@lists.ettus.com

I'll note that 'S' errors generally indicate that packets are being
dropped somewhere in the network stack after they leave UHD, and before
they get delivered to the radio.

What type of network interface do you have on your 64-core server?   
Are we maybe dealing with a PHY-level issue
  that is dropping frames?

What OS are you using?  Is this within a VM or on "base metal"??

On 27/06/2024 15:41, cjohnson@serranosystems.com wrote: > > Hi, > > Can you help me figure out what the problem is using the modified > example (I provided in last response), a fast machine which has the > tips and tricks implemented? > > I directly connected our 64 core / 4 GPU / >250GI RAM workstation with > 10G output directly to the X310 10G, which should easily keep up with > 200Msps. > > I ran the same program I provided above (I just modified your example > program tx_timed_samples.cpp) and now it outputs S’s instead of U’s. > > Here is the output: > > |cjohnson@demo:~/uhd_versions/uhd_4.4.0.0/host/build/examples$ > ./tx_timed_samples Creating the usrp device with: > type=x300,addr=192.168.30.2... [INFO] [UHD] linux; GNU C++ version > 11.4.0; Boost_107400; UHD_4.4.0.HEAD-0-g5fac246b [INFO] [X300] X300 > initialization sequence... [INFO] [X300] Maximum frame size: 8000 > bytes. [INFO] [GPS] Found an internal GPSDO: LC_XO, Firmware Rev > 0.929a [INFO] [X300] Radio 1x clock: 200 MHz Using Device: Single > USRP: Device: X-Series Device Mboard 0: X310 RX Channel: 0 RX DSP: 0 > RX Dboard: A RX Subdev: UBX RX RX Channel: 1 RX DSP: 1 RX Dboard: B RX > Subdev: UBX RX TX Channel: 0 TX DSP: 0 TX Dboard: A TX Subdev: UBX TX > TX Channel: 1 TX DSP: 1 TX Dboard: B TX Subdev: UBX TX Setting TX > Rate: 200.000000 Msps... Actual TX Rate: 200.000000 Msps... Setting > device timestamp to 0... [WARNING] [0/Radio#0] Attempting to set tick > rate to 0. Skipping. Send timeout... Send timeout... Send timeout... > Send timeout... Send timeout... Send timeout... Send timeout... > SSSSSSSS (... more S's)| > > I verified the interface is setup for 9000 MTU, and that I have made > the adjustments indicated in > https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks > except for Specture / bios changes). This includes Ring Buffers for > NIC and Network Buffers > > |(Below, same for CPU 0-63) analyzing CPU 63: driver: intel_cpufreq > CPUs which run at the same hardware frequency: 63 CPUs which need to > have their frequency coordinated by software: 63 maximum transition > latency: 20.0 us. hardware limits: 800 MHz - 3.50 GHz available > cpufreq governors: conservative, ondemand, userspace, powersave, > performance, schedutil current policy: frequency should be within 800 > MHz and 3.50 GHz. The governor "performance" may decide which speed to > use within this range. current CPU frequency is 3.50 GHz.| > > > > _______________________________________________ > USRP-users mailing list --usrp-users@lists.ettus.com > To unsubscribe send an email tousrp-users-leave@lists.ettus.com I'll note that 'S' errors generally indicate that packets are being dropped somewhere in the network stack after they leave UHD, and before they get delivered to the radio. What type of network interface do you have on your 64-core server?    Are we maybe dealing with a PHY-level issue   that is dropping frames? What OS are you using?  Is this within a VM or on "base metal"??
C
cjohnson@serranosystems.com
Thu, Jun 27, 2024 10:11 PM

Hi, Did you give the modified host/examples/tx_timed_samples.cpp I provided above a try?  This maybe the best first path to go down, to make sure it is not a UHD thing.  You can just replace the current tx_timed_samples.cpp with this one (2 threads ago), then make in (for example) “~/uhd-4.4.0.0/host/build”.  Output is in “~/uhd-4.4.0.0/host/build/examples” as tx_timed_samples.

This is an actual server (64 core) running ubuntu 22.04

~$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 22.04.4 LTS
Release:        22.04
Codename:       jammy

Hi, Did you give the modified host/examples/tx_timed_samples.cpp I provided above a try? This maybe the best first path to go down, to make sure it is not a UHD thing. You can just replace the current tx_timed_samples.cpp with this one (2 threads ago), then make in (for example) “\~/uhd-4.4.0.0/host/build”. Output is in “\~/uhd-4.4.0.0/host/build/examples” as tx_timed_samples. This is an actual server (64 core) running ubuntu 22.04 ``` ~$ lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 22.04.4 LTS Release: 22.04 Codename: jammy ```
MD
Marcus D. Leech
Thu, Jun 27, 2024 10:59 PM

On 27/06/2024 18:11, cjohnson@serranosystems.com wrote:

Hi, Did you give the modified host/examples/tx_timed_samples.cpp I
provided above a try? This maybe the best first path to go down, to
make sure it is not a UHD thing. You can just replace the current
tx_timed_samples.cpp with this one (2 threads ago), then make in (for
example) “~/uhd-4.4.0.0/host/build”. Output is in
“~/uhd-4.4.0.0/host/build/examples” as tx_timed_samples.

This is an actual server (64 core) running ubuntu 22.04

|~$ lsb_release -a No LSB modules are available. Distributor ID:
Ubuntu Description: Ubuntu 22.04.4 LTS Release: 22.04 Codename: jammy |


USRP-users mailing list --usrp-users@lists.ettus.com
To unsubscribe send an email tousrp-users-leave@lists.ettus.com

Unfortunately, the X310 I currently have access to has no TX-capable
boards configured, so I can't test your code.

On 27/06/2024 18:11, cjohnson@serranosystems.com wrote: > > Hi, Did you give the modified host/examples/tx_timed_samples.cpp I > provided above a try? This maybe the best first path to go down, to > make sure it is not a UHD thing. You can just replace the current > tx_timed_samples.cpp with this one (2 threads ago), then make in (for > example) “~/uhd-4.4.0.0/host/build”. Output is in > “~/uhd-4.4.0.0/host/build/examples” as tx_timed_samples. > > This is an actual server (64 core) running ubuntu 22.04 > > |~$ lsb_release -a No LSB modules are available. Distributor ID: > Ubuntu Description: Ubuntu 22.04.4 LTS Release: 22.04 Codename: jammy | > > _______________________________________________ > USRP-users mailing list --usrp-users@lists.ettus.com > To unsubscribe send an email tousrp-users-leave@lists.ettus.com Unfortunately, the X310 I currently have access to has no TX-capable boards configured, so I can't test your code.