TLS 线程局部变量, 网上一堆文章说比用锁要好, 为什么我测试了后和 CRITICAL_SECTION 差不多呢

Sandrer 2018-10-25 11:18:20
之前开发的程序一直在用 TLS, 各线程玩各自的东西
但这段时间要优化一个服务端程序, 就想着能不能再优化一下 TLS 的东西
然后就写了下面的代码, 但运行结果看来, TLS 和 CRITICAL_SECTION 差不多的时间
反而很多时候要比 CS 慢.........................
难道是我打开的方式不对???

#include "stdafx.h"
#include <process.h>

static DWORD m_dwTLSIndex = 0;

static CRITICAL_SECTION m_lock;

#define MAX_ALLOCATE 1000000u
static volatile DWORD m_dwAllocCount = 0;

struct BUFFER
{
BUFFER *next;
BYTE data[16];
};

struct BUFFER_LIST
{
BUFFER_LIST *next;
BUFFER *pBuffers;
};

static BUFFER_LIST *m_pBufferList = NULL;
static BUFFER *m_pBuffers = NULL;

uintptr_t __stdcall _thread1(void *)
{
BUFFER *p;
BUFFER_LIST *pList = (BUFFER_LIST *)malloc(sizeof(BUFFER_LIST));
ZeroMemory(pList, sizeof(BUFFER_LIST));

::EnterCriticalSection(&m_lock);
pList->next = m_pBufferList;
m_pBufferList = pList;
::LeaveCriticalSection(&m_lock);

::TlsSetValue(m_dwTLSIndex, pList);

for (;;)
{
p = (BUFFER *)malloc(sizeof(BUFFER));
p->data[0] = 0;

pList = (BUFFER_LIST *)::TlsGetValue(m_dwTLSIndex);
p->next = pList->pBuffers;
pList->pBuffers = p;

if (InterlockedIncrement(&m_dwAllocCount) >= MAX_ALLOCATE)
break;
}

return 0;
}

uintptr_t __stdcall _thread2(void *)
{
BUFFER *p;

for (;;)
{
p = (BUFFER *)malloc(sizeof(BUFFER));
p->data[0] = 0;

::EnterCriticalSection(&m_lock);
p->next = m_pBuffers;
m_pBuffers = p;
::LeaveCriticalSection(&m_lock);

if (InterlockedIncrement(&m_dwAllocCount) >= MAX_ALLOCATE)
break;
}

return 0;
}

void TestTLSData()
{
::InitializeCriticalSection(&m_lock);

ULONGLONG ullBegin, ullEnd;
SYSTEM_INFO si;
::GetSystemInfo(&si);

DWORD dwThread = 0;
DWORD dwCount = si.dwNumberOfProcessors;
HANDLE *phThreads = new HANDLE[dwCount + 1];
ZeroMemory(phThreads, sizeof(HANDLE) * (dwCount + 1));

m_dwTLSIndex = ::TlsAlloc();

::GetSystemTimeAsFileTime((LPFILETIME)&ullBegin);

dwThread = 0;
while (dwCount--)
phThreads[dwThread++] = (HANDLE)_beginthreadex(NULL, 0, _thread1, NULL, 0, NULL);

::WaitForMultipleObjects(dwThread, phThreads, TRUE, INFINITE);

::GetSystemTimeAsFileTime((LPFILETIME)&ullEnd);
printf("Used TLS: %u.%04u ms\n", (DWORD)(ullEnd - ullBegin) / 10000, (DWORD)(ullEnd - ullBegin) % 10000);
while (dwThread--)
::CloseHandle(phThreads[dwThread]);

::TlsFree(m_dwTLSIndex);

BUFFER *n, *p;
//BUFFER_LIST *pNext;
//BUFFER_LIST *pList = m_pBufferList;
//while (pList != NULL)
//{
// pNext = pList->next;

// p = pList->pBuffers;
// while (p)
// {
// n = p->next;
// free(p);
// p = n;
// }

// free(pList);
// pList = pNext;
//}

m_dwAllocCount = 0;
dwCount = si.dwNumberOfProcessors;
ZeroMemory(phThreads, sizeof(HANDLE) * (dwCount + 1));

::GetSystemTimeAsFileTime((LPFILETIME)&ullBegin);

dwThread = 0;
while (dwCount--)
phThreads[dwThread++] = (HANDLE)_beginthreadex(NULL, 0, _thread2, NULL, 0, NULL);

::WaitForMultipleObjects(dwThread, phThreads, TRUE, INFINITE);

::GetSystemTimeAsFileTime((LPFILETIME)&ullEnd);
printf("Not used TLS: %u.%04u ms\n", (DWORD)(ullEnd - ullBegin) / 10000, (DWORD)(ullEnd - ullBegin) % 10000);
while (dwThread--)
::CloseHandle(phThreads[dwThread]);

//p = m_pBuffers;
//while (p)
//{
// n = p->next;
// free(p);
// p = n;
//}

::DeleteCriticalSection(&m_lock);

system("pause");
}
...全文
157 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
tls本来就应该比cs方式要慢,因为它本身是为了安全而准备,而不是为效率,如果安全性要求高你可以用,如果安全性要求不高,那还是cs的形式最为方便快捷,你可以详细了解下tls的协议就知道了,本协议为了安全性付出了很多时间上的代价,比如加密,比如额外的协议层数据
赵4老师 2018-10-26
  • 打赏
  • 举报
回复
无profiler不要谈效率!!尤其在这个云计算、虚拟机、模拟器、CUDA、多核 、多级cache、指令流水线、多种存储介质、……满天飞的时代!

15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧