Skip to content

fastdds的 RTPS_DllAPI bool write(void* data);函数执行时间非常久 #5666

Open
@colder20040320

Description

@colder20040320

Is there an already existing issue for this?

  • I have searched the existing issues

Expected behavior

每次调用接口都会将5.5MB的数据发送给订阅者,发送不应该有延迟,接收端能流畅播放数据

Current behavior

每次调用接口都能发送5.5MB的数据,但一次write函数执行完成需要大约0.6s,(已经确定接收端对于到达的数据能够快速接收)

Steps to reproduce

1.一台电脑扮演订阅者,另一台电脑扮演发布者,都是windows平台
2.发布者频繁调用write函数将数据发送给fastdds
3.接收端频繁调用take_next_example读取数据

Fast DDS version/commit

不太清除具体版本,但使用的lib库是 fastcdr-2.2.lib, fastrtps-2.14.lib

Platform/Architecture

Other. Please specify in Additional context section.

Transport layer

Default configuration, UDPv4 & SHM

Additional context

电脑配置:两台windows11,3060显卡 vs2019

以下是接收方的设置:

DomainParticipantQos pqos = PARTICIPANT_QOS_DEFAULT;
pqos.name("spos_participant");
pqos.properties().properties().emplace_back("fastdds.type_propagation", "enabled");     /*  开启类型传播  */
pqos.wire_protocol().builtin.typelookup_config.use_client = false;
pqos.wire_protocol().builtin.typelookup_config.use_server = true;
eprosima::fastdds::dds::DomainParticipant* ddsparticipant = DomainParticipantFactory::get_instance()->create_participant(1, pqos);

virtual bool CreateDataReader(void* participant)
{
bool res = false;
if(!m_isDataReaderRegistered)
{
GetStructSize(m_datasize);
eprosima::fastdds::dds::DomainParticipant* participant_ = static_casteprosima::fastdds::dds::DomainParticipant*(participant);
if (m_fixedDataType)
{
m_fixedDataType.register_type(participant_);
m_fixedDataType->auto_fill_type_object(true);
m_fixedDataType->auto_fill_type_information(true);
m_ddssubscriber = participant_->create_subscriber(eprosima::fastdds::dds::SUBSCRIBER_QOS_DEFAULT, nullptr);
topic_ = participant_->create_topic(m_topicname, m_fixedDataType.get_type_name(), eprosima::fastdds::dds::TOPIC_QOS_DEFAULT);
eprosima::fastdds::dds::DataReaderQos rqos= eprosima::fastdds::dds::DATAREADER_QOS_DEFAULT;
rqos.reliability().kind = eprosima::fastdds::dds::BEST_EFFORT_RELIABILITY_QOS;
rqos.history().kind = eprosima::fastdds::dds::KEEP_LAST_HISTORY_QOS;
m_ddsreader = m_ddssubscriber->create_datareader(topic_, rqos, &m_Sublistener);
m_isDataReaderRegistered = true;

以下是发送者的配置:
DomainParticipantQos pqos = PARTICIPANT_QOS_DEFAULT;
pqos.name("spos_participant");
pqos.properties().properties().emplace_back("fastdds.type_propagation", "enabled"); /* 开启类型传播 /
pqos.wire_protocol().builtin.typelookup_config.use_client = false;
pqos.wire_protocol().builtin.typelookup_config.use_server = true;
eprosima::fastdds::dds::DomainParticipant
ddsparticipant = DomainParticipantFactory::get_instance()->create_participant(1, pqos);

virtual bool CreateDataWriterFix(void* participant)
{
bool res = false;
if(!m_isDataWriterRegistered)
{
GetStructSize(m_datasize);
eprosima::fastdds::dds::DomainParticipant* participant_ = static_casteprosima::fastdds::dds::DomainParticipant*(participant);
if (m_fixedDataType)
{

                    m_fixedDataType.register_type(participant_);
                    m_fixedDataType->auto_fill_type_object(true);
                    m_fixedDataType->auto_fill_type_information(false);
                    publisher_ = participant_->create_publisher(eprosima::fastdds::dds::PUBLISHER_QOS_DEFAULT, nullptr);
                    topic_ = participant_->create_topic(m_topicname, m_fixedDataType.get_type_name(), eprosima::fastdds::dds::TOPIC_QOS_DEFAULT);
                    eprosima::fastdds::dds::DataWriterQos writer_qos = eprosima::fastdds::dds::DATAWRITER_QOS_DEFAULT;
                    writer_qos.reliability().kind = eprosima::fastdds::dds::BEST_EFFORT_RELIABILITY_QOS;
                    writer_qos.history().kind = eprosima::fastdds::dds::KEEP_LAST_HISTORY_QOS;
                    writer_ = publisher_->create_datawriter(topic_, writer_qos, &m_Publistener_);
                    m_isDataWriterRegistered = true;

XML configuration file

Relevant log output

发送端输出代码
clock_t start_time = clock();
writer_->writer(data);
clock_t end_time = clock();
                    double elapsed_time = double(end_time - start_time) / CLOCKS_PER_SEC;
                    std::cout << "Function ConvertReadData took " << elapsed_time << " seconds to run." << std::endl;

发送端打印的时间大约是0.5s;

接收端输出代码
 clock_t start_time = clock();
                    if(m_ddsreader->take_next_sample(srtdataptr, &info) == ReturnCode_t::RETCODE_OK)
                    {
                        if (info.valid_data)
                        {
                            res = ConvertReadData(srtdataptr, dstdata);
                        }
                    }    
                    else
                    {
                        std::cout << "can't get next_sample " << std::endl;
                    }
                    clock_t end_time = clock();
                    double elapsed_time = double(end_time - start_time) / CLOCKS_PER_SEC;
                    std::cout << "Function ConvertReadData took " << elapsed_time << " seconds to run." << std::endl;
                }

接收端打印的时间约0.001s

Network traffic capture

Image
如图,Time表示编号2065的数据包到达抓包工具的时间戳(56.619),framentStartingNum表示当前分片的起始编号为1

Image
如图,Time表示编号13411的数据包到达抓包工具的时间戳(57.556),framentStartingNum表示当前分片的起始编号为85,这是单次发送数据的最后一个分片,可得发送端发送一次数据(5529640字节)(5.5MB)需要分片85次,一次分片的大小是65324字节(63KB).
以上是发送端的网络包情况

以下是接收端的网络包情况:

Image
如图,这是发送端发送过来的第一个分片,到达接收端的抓包工具的时间戳(56.657),和到达发送端的抓包工具的时间戳(56.619)相差0.038s.

iperf工具测试网络带宽:
Image

Image

Metadata

Metadata

Assignees

No one assigned

    Labels

    triageIssue pending classification

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions