False sharing in multi-processor systems 2-program demonstration

Source: Internet
Author: User

Original article: http://blog.csdn.net/sy8111/archive/2006/09/05/1178107.aspx

 

The following uses a simple applet to verify the impact of false sharing on performance.

 

This applet runs two threads at the same time to read and write the int size of the same memory area for multiple times. Thread 1 reads and writes 1st int values, and thread 2 reads and writes 2nd int values. As expected, if the two intns are too close to each other and fall into the same cache line, the two threads will spend additional time communicating and maintaining cache consistency because of "pseudo-sharing, this causes performance degradation.

 

Testfalsesharing. cpp is the main program, and thread. h/CPP is a simple encapsulation of Win32 thread APIs. Timer. h/CPP is a simple encapsulation of CRT time functions.

 

// Testfalsesharing. CPP </P> <p> # include "stdafx. H "<br/> # include" thread. H "<br/> # include" timer. H "</P> <p> # define count 3000000000 <br/> # define distance 4 </P> <p> DWORD winapi t1_p (void *) <br/> {<br/> int * arr = (int *) A; <br/> for (INT I = 0; I <count; I ++) <br/> arr [0] = 30; </P> <p> return 0; <br/>}</P> <p> DWORD winapi t2_p (void * A) <br/>{< br/> int * arr = (int *); <br/> for (INT I = 0; I <count; I ++) <br/> arr [distance] = 30; </P> <p> return 0; <br/>}</P> <p> int arr [64]; </P> <p> int main (INT argc, char * argv []) <br/>{< br/> yshi: timer (STD: cout); </P> <p> // start threads <br/> yshi :: winthread T1 (t1_p, arr); <br/> yshi: winthread T2 (t2_p, arr ); </P> <p> // wait for all threads to terminate <br/> t1.wait (); <br/> t2.wait (); </P> <p> timer. stop (); </P> <p> return 0; <br/>}

 

// Thread. h </P> <p> namespace yshi <br/>{</P> <p> typedef lpthread_start_routine winthreadproc; // int func_name (void *) </P> <p> // This class is exported from the win32.dll <br/> class win32_api winthread <br/>{< br/> public: <br/> winthread (winthreadproc aproc, void * aparam, bool asuspend = false); <br/> void resume (); <br/> void wait (); <br/> virtual ~ Winthread (); <br/> PRIVATE: <br/> handle _ HANDLE; <br/> PRIVATE: <br/> winthread (const winthread &); <br/> winthread & operator = (const winthread &); <br/>}; </P> <p>}

 

// Thread. CPP </P> <p> # include "stdafx. H "<br/> # include" thread. H "</P> <p> namespace yshi <br/>{</P> <p> winthread: winthread (winthreadproc aproc, void * aparam, bool asuspend) <br/> {<br/> handle H = createthread (null, 0, aproc, aparam, asuspend? 0x04: 0x00, null); <br/> If (H = NULL) <br/>{< br/> throw getlasterror (); <br/>}</P> <p> _ HANDLE = H; <br/>}</P> <p> void winthread: Resume () <br/>{< br/> DWORD ret = resumethread (_ HANDLE); <br/> If (ret =-1) <br/>{< br/> throw getlasterror (); <br/>}</P> <p> void winthread: Wait () <br/>{ <br/> DWORD ret = waitforsingleobject (_ HANDLE, infinite); <br/> If (ret = wait_failed) <br/> throw getlasterror () ; <Br/>}</P> <p> winthread ::~ Winthread () <br/>{< br/> If (_ HANDLE! = 0) <br/> closehandle (_ HANDLE); <br/>}</P> <p>}

 

// Timer. h </P> <p> namespace yshi <br/>{</P> <p> class debugutil_api timer <br/>{< br/> public: <br/> timer (STD: ostream & aoutput); <br/> ~ Timer (); <br/> void start (); <br/> void stop (); <br/> PRIVATE: <br/> void print (STD :: ostream & aoutput); <br/> PRIVATE: <br/> STD: ostream & moutput; <br/> unsigned long mtimediff; <br/> PRIVATE: <br/> timer & operator = (const timer &); <br/>}; </P> <p>}

 

// Timer. CPP </P> <p> # include "timer. H "</P> <p> # include <ctime> </P> <p> namespace yshi <br/>{</P> <p> Timer :: timer (STD: ostream & aoutput): moutput (aoutput) <br/>{< br/> Start (); <br/>}</P> <p> Timer ::~ Timer () <br/>{< br/>}</P> <p> void Timer: Start () <br/>{< br/> mtimediff = time (0); <br/>}</P> <p> void Timer: Stop () <br/>{< br/> mtimediff = time (0)-mtimediff; <br/> Print (moutput ); <br/>}</P> <p> void Timer: Print (STD: ostream & aoutput) <br/>{< br/> aoutput <"time spent:" <mtimediff <"seconds/N "; <br/>}</P> <p>}

 

Running result

 

Data distance (distance) elapsed time (seconds)

4 21

8 21

16 10

32 10

 

We can see that when the distance reaches 16 int, that is, 64 bytes, "pseudo-sharing" disappears, and 64 bytes is the cache line size of my machine.

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.