マルチスレッドとキャッシュ
キャッシュを意識したプログラム。
どこかのサイトか忘れたけど、記事があったのでプログラム書いてみた。
要はメモリレベルでのスレッド間の独立性を高める。
ソース
#include <cstdio> #include <process.h> #include <Windows.h> #include <conio.h> // スレッド #define THREAD_NUM 4 unsigned int __stdcall SubEntity0(void*);// スレッド0 unsigned int __stdcall SubEntity1(void*);// スレッド1 unsigned int __stdcall SubEntity2(void*);// スレッド2 unsigned int __stdcall SubEntity3(void*);// スレッド3 void func(const int idx ); // テスト用関数 // スレッドごとのアクセスデータ //#define ST_SIZE (1<<7) //128 #define ST_SIZE (1<<5) //32 struct THREAD_DATA { int cnt; unsigned char pad[ST_SIZE-sizeof(int)]; }; static THREAD_DATA s_threadData[THREAD_NUM] = {}; void main(void) { int ver[(sizeof(THREAD_DATA)==ST_SIZE)?1:0] ={1}; // スレッドリスト typedef unsigned int (__stdcall * ThreadEntry) (void *); ThreadEntry thread[THREAD_NUM] = { SubEntity0, SubEntity1, SubEntity2, SubEntity3, }; printf("BLOCK SIZE:%d\n", ST_SIZE ); int total = 0; for( int i = 0; i < 10; ++i ) { HANDLE hSub[THREAD_NUM] = {}; unsigned int sub[THREAD_NUM] = {}; for( int x = 0; x < THREAD_NUM; ++x){ hSub[x] = (HANDLE)_beginthreadex( NULL, 0, thread[x], NULL, 0, &sub[x] ); } DWORD beginTime = timeGetTime(); WaitForMultipleObjects(THREAD_NUM, hSub, TRUE, INFINITE ); DWORD endTime = timeGetTime(); printf("[%02d]DiffTime:%d\n", i, endTime-beginTime ); total += endTime-beginTime; for(int x=0; x<THREAD_NUM; ++x){ CloseHandle(hSub[x]); } } printf("Avg:%f", (float)total/10.0f); _getch(); } unsigned int __stdcall SubEntity0(void*){ func(0); _endthreadex(0); return 0; } unsigned int __stdcall SubEntity1(void*){ func(1); _endthreadex(0); return 0; } unsigned int __stdcall SubEntity2(void*){ func(2); _endthreadex(0); return 0; } unsigned int __stdcall SubEntity3(void*){ func(3); _endthreadex(0); return 0; } void func(const int idx) { for( int i = 0; i < 150000000; ++i){ ++s_threadData[idx].cnt; s_threadData[idx].cnt *= s_threadData[idx].cnt; } }
結果
ブロックサイズ | 時間[ms] |
128 | 823.1ms |
32 | 1356.0ms |
まとめ
だいたいのマルチコアはコアごとにキャッシュを持っているので、
キャッシュがかぶらないようにある程度、アクセス領域を離す必要がある。
自分のPCではキャッシュの取得幅は128byteだった。
CPUによって取得サイズは異なると思う。システムから取得できる方法はあるか分からない。