簡體   English   中英

IPC在C ++ TCP中首先進行send()和recv()調用需要更長的時間

[英]IPC First send() and recv() calls in C++ TCP takes longer

我使用IPC(進程間通信)來發送兩個C ++程序之間的數據。 對於IPC我使用基本的TCP / IP的Winsock2代碼。

基本想法是,我發送兩個應用程序之間的3D數據幀,一個處理使用GPU / CUDA並使用3DE方庫(PCL)它的其他顯示器的數據。 我的應用程序中的數據非常豐富(例如30fps,每幀4Mb),但是據我所知,這對於IPC來說應該不是問題。

從而每幀完成在GPU上處理,I幀數據(X,Y,float類型ŽCOORDS; R,G,B型的uint8_t每個)轉換為字節,並將它們發送一個接一個。

這樣做我注意到一個奇怪的現象。 在我的代碼我有9的send()命令,一前一后。

  • 1ste:發送一個作為幀的名稱的單個字符。
  • 2DE:與3D的量單個int傳入點。
  • 3-5日:RGB值
  • 6-8th:XYZ值
  • 第9個:結束通訊檢查以關閉查看器應用程序。

這整個過程需要30毫秒〜完成。 我發現奇怪的是,大多數的時間去了。 定時每次活動后,我得到了以下內容:

  • 1ste:20毫秒(1周字節的數據)
  • 2DE:<1毫秒(4個字節的數據)
  • 3-5:2ms的(921600個字節的數據)
  • 6-8:3毫秒(3686400個字節的數據)
  • 第九:1毫秒(1周字節的數據)

為什么對於第一個send命令來說,即使只有1個字節的數據,也要花很長時間才能完成,然后其余數據在記錄時間內完成。 在這每一個循環運行時間之間,存在約20ms的延時等待GPU的代碼來完成。 請問TCP連接進入睡眠狀態,如果是這樣我可以以某種方式將其禁用。

TCP套接字代碼:

SOCKET Create_Server_Socket(PCSTR IP, PCSTR port)
{
struct addrinfo *result = NULL, *ptr = NULL, hints;
int iResult;

ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE;

// Resolve the local address and port to be used by the server
iResult = getaddrinfo(NULL, port, &hints, &result);
if (iResult != 0) {
    printf("getaddrinfo failed: %d\n", iResult);
    WSACleanup();
    return 1;
}

SOCKET ListenSocket = INVALID_SOCKET;

ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);

if (ListenSocket == INVALID_SOCKET) {
    printf("Error at socket(): %ld\n", WSAGetLastError());
    freeaddrinfo(result);
    WSACleanup();
    return 1;
}

iResult = bind(ListenSocket, result->ai_addr, (int)result->ai_addrlen);
if (iResult == SOCKET_ERROR) {
    printf("bind failed with error: %d\n", WSAGetLastError());
    freeaddrinfo(result);
    closesocket(ListenSocket);
    WSACleanup();
    return 1;
}

freeaddrinfo(result);

if (listen(ListenSocket, SOMAXCONN) == SOCKET_ERROR) {
    printf("Listen failed with error: %ld\n", WSAGetLastError());
    closesocket(ListenSocket);
    WSACleanup();
    return 1;
}

SOCKET ClientSocket;

ClientSocket = INVALID_SOCKET;

// Accept a client socket
ClientSocket = accept(ListenSocket, NULL, NULL);
if (ClientSocket == INVALID_SOCKET) {
    printf("accept failed: %d\n", WSAGetLastError());
    closesocket(ListenSocket);
    WSACleanup();
    return 1;
}

return (ClientSocket);

}

有問題的代碼:

iResult = send(ConnectSocket, (char*)&name, sizeof(char), 0);  //Takes >20ms to complete
iResult = send(ConnectSocket, (char*)&points, 4, 0);
iResult = send(ConnectSocket, (char*)Red_t, sizeof(uint8_t) * depth_width *depth_height, 0);
iResult = send(ConnectSocket, (char*)Green_t, sizeof(uint8_t) * depth_width *depth_height, 0);
iResult = send(ConnectSocket, (char*)Blue_t, sizeof(uint8_t) * depth_width *depth_height, 0);
iResult = send(ConnectSocket, (char*)z_t, sizeof(uint16_t) * depth_width *depth_height, 0);
iResult = send(ConnectSocket, (char*)x_t, sizeof(float) * depth_width *depth_height, 0)
iResult = send(ConnectSocket, (char*)y_t, sizeof(float) * depth_width *depth_height, 0);
iResult = send(ConnectSocket, "a", sizeof(char), 0);

我工作在Windows 10(即Winsock2的LIB)。

先感謝您!

您可能正遭受“ Nagle算法”的懲罰,請參見https://en.wikipedia.org/wiki/Nagle%27s_algorithm

長話短說,TCP / IP內置了延遲,目的是在發送第一個數據包之前收集足夠的數據以值得發送一個數據包。 如果您遇到問題,打開套接字時可以使用一個TCP_NODELAY選項來禁用它。

話雖如此,如果性能至關重要,那么最好使用共享內存進行進程間通信,而不是使用套接字。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM