我有一個多線程套接字程序。我使用boost線程池(http://threadpool.sourceforge.net/)執行任務。我在threadpool中爲每個線程創建一個TCP客戶端套接字。每當我發送大量的數據,比如說500KB(消息大小),吞吐量就會大大降低。我檢查我的代碼爲:如何測量和修復上下文切換瓶頸?
1)等待可能導致上下文切換 2)鎖定/互斥
例如,500KB消息被劃分爲多個行和我發送通過使用插座的每一行: :send()。
typedef std::list<std::string> LinesListType;
// now send the lines to the server
for (LinesListType::const_iterator it = linesOut.begin();
it!=linesOut.end();
++it)
{
std::string line = *it;
if (!line.empty() && '.' == line[0])
{
line.insert(0, ".");
}
SendData(line + CRLF);
}
的SendData:
void SendData(const std::string& data)
{
try
{
uint32_t bytesToSendNo = data.length();
uint32_t totalBytesSent = 0;
ASSERT(m_socketPtr.get() != NULL)
while (bytesToSendNo > 0)
{
try
{
int32_t ret = m_socketPtr->Send(data.data() + totalBytesSent, bytesToSendNo);
if (0 == ret)
{
throw;
}
bytesToSendNo -= ret;
totalBytesSent += ret;
}
catch()
{
}
}
}
catch()
{
}
}
發送方法在客戶端套接字:因爲::選擇
int Send(const char* buffer, int length)
{
try
{
int bytes = 0;
do
{
bytes = ::send(m_handle, buffer, length, MSG_NOSIGNAL);
}
while (bytes == -1 && errno == EINTR);
if (bytes == -1)
{
throw SocketSendFailed();
}
return bytes;
}
catch()
{
}
}
調用::選擇()之前發送引起的上下文切換能阻斷。對共享互斥鎖持有鎖會導致並行線程等待並切換上下文。這影響了性能。
是否有避免上下文切換,特別是在網絡編程中的最佳做法?我花了至少一個星期的時間試圖找出各種不用運氣的工具(vmstat,valgrind中的callgrind)。 Linux上的任何工具都有助於衡量這些瓶頸?
爲什麼你認爲上下文切換和/或鎖/互斥是問題?這500KB,是每秒?是來自一個客戶端的加載還是來自多個客戶端的聚合加載?另外,沒有代碼:( –
> Linux上的任何工具都有助於測量這些瓶頸? 'perf記錄-e cs -g -p PID'。https://perf.wiki.kernel.org/index.php/Tutorial# Sampling_with_perf_record。但是,您提供的信息很少,以確保上下文切換對此負責。 –
@MartinJames我已經更新了這個問題,使其更加清晰。我無法分享代碼,因爲它跨越了多個文件。 – ssk