<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.expertiza.ncsu.edu/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Pmpatel</id>
	<title>Expertiza_Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.expertiza.ncsu.edu/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Pmpatel"/>
	<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=Special:Contributions/Pmpatel"/>
	<updated>2026-05-14T09:22:24Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.41.0</generator>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_506_Spring_2011/ch7_jp&amp;diff=44592</id>
		<title>CSC/ECE 506 Spring 2011/ch7 jp</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_506_Spring_2011/ch7_jp&amp;diff=44592"/>
		<updated>2011-03-22T02:42:41Z</updated>

		<summary type="html">&lt;p&gt;Pmpatel: /* Introduction */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Introduction=&lt;br /&gt;
&lt;br /&gt;
Shared memory architecture is one of the two major classes of large computer systems architecture.  In a shared memory architecture, physical memory from all the processors is mapped into a single memory map.  All the processors can potentially access to all the memory on the system, although access time could be different (eg NUMA).  Different threads or processes can communicate by reading/writing to shared memory.&lt;br /&gt;
&lt;br /&gt;
==Advantages of shared memory system==&lt;br /&gt;
&lt;br /&gt;
* Shared memory parallel programs and multi-threaded programs will automatically run on shared memory system.&lt;br /&gt;
* Single OS runs on shared memory system which simplifies maintenance, memory management and scheduler tasks.&lt;br /&gt;
* Amount of total memory is large as it is simply sum of all memory of individual nodes.&lt;br /&gt;
* Communicating data between caches is faster than that in message passing model.&lt;br /&gt;
* Ability of finer granularity sharing compared to message passing which adds overhead of creating/sending messages for each bit of information.&lt;br /&gt;
* Common data types can be shared between different threads running on different processors. (eg. shared data which is Read Only)&lt;br /&gt;
&lt;br /&gt;
==Disadvantages of shared memory system==&lt;br /&gt;
&lt;br /&gt;
* Cost of providing shared memory grows super linearly with number of processors compared to message passing model which grows linearly.&lt;br /&gt;
&lt;br /&gt;
==Hardware Support ==&lt;br /&gt;
Shared memory architecture needs some hardware support for the implementation unlike a message passing model which can rely on software for send and receive messages.  Three things necessary with respect to hardware support for correct execution of a shared memory parallel program on a multiprocessor system are: &lt;br /&gt;
# Cache Coherence protocol&lt;br /&gt;
# Memory consistency model&lt;br /&gt;
# Hardware Synchronization&lt;br /&gt;
&lt;br /&gt;
=Cache Coherence Problem=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:sharedmem.jpg|thumbnail|right|600px|Shared Memory system with dedicated Cache for each processor&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#4foot|[4]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;]]	&lt;br /&gt;
&lt;br /&gt;
In a system with single processor (single core), maintaining cache coherency is simple and easy but in a multiprocessor system, it is not as simple.  Data can be present in any processors cache and protocol needs to ensure that the data is same in all caches.  If it cannot ensure that all the caches are same, then it needs to flag a cache line indicating that it is not updated.  &lt;br /&gt;
&lt;br /&gt;
In the figure shown here, this is a 4 processor shared memory system where each processor has its own cache.  Supposed processor P1 reads memory location M1 and stores it in its local cache.  Then, if P2 reads same location memory location then M1 gets stored in P2’s cache.  Now, if P1 changes value of M1, two copies of same data, residing in different caches will become different.  When P2 operates on M1, it uses the stale value of M1 that was stored in its cache.  It is responsibility of Cache Coherence Protocol to prevent this.  Hardware support is needed to provide a coherent view of data in multiple caches.  This is known as write propagation requirement.&lt;br /&gt;
&lt;br /&gt;
One may think that cache write policy can provide cache coherence but it is not true.  Cache write policy only controls how a change in value of cache is propagated to lower level cache or main memory.  It is not responsible for propagating changes to other caches.&lt;br /&gt;
&lt;br /&gt;
=Memory Consistency Problem=&lt;br /&gt;
&lt;br /&gt;
Memory consistency deals with the ordering of memory operations (load and store) to different memory locations.  In a single processor system, code will execute correctly if the compiler preservers the order of the access to synchronization variables and other dependent variables.  But in shared memory model with multiple processors, two threads could be access a shared data (something like a synchronization variable) and the output of the threads could change based on which thread can get to the shared data earlier.  If this happens, then the program output on uni-processor system and multi-processor program will be different.&lt;br /&gt;
&lt;br /&gt;
Maintaining program order is very important for memory consistency but it comes with performance degradation.  Various memory consistency models trades off performance to make programming easy.   &lt;br /&gt;
&lt;br /&gt;
=Peterson's Algorithm=&lt;br /&gt;
Peterson’s algorithm, also known as Peterson’s solution, is an algorithm that addresses the critical section problem by meeting the 3 criteria of the problem: mutual exclusion, progress, and bounded waiting&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;1body&amp;quot;&amp;gt;[[#1foot|[1]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 int turn;  // turn for execution&lt;br /&gt;
 int interested[2];   // the processors interested&lt;br /&gt;
 void enter_region(int process) &lt;br /&gt;
 { &lt;br /&gt;
   int otherProcess; &lt;br /&gt;
   otherProcess = 1 - process;    &lt;br /&gt;
   interested[process]=1;  &lt;br /&gt;
   turn = process;         &lt;br /&gt;
   while(turn == process &amp;amp;&amp;amp; interested[otherProcess] == 1)&lt;br /&gt;
      {&lt;br /&gt;
  	// busy wait&lt;br /&gt;
      }&lt;br /&gt;
 } &lt;br /&gt;
 void leave_region(int process) &lt;br /&gt;
 { &lt;br /&gt;
   interested[process] = 0; &lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
The algorithm uses two variables as seen above, interested and turn.  If a flag value for interested is set to 1, it indicates the process wants to enter the critical section.  The variable turn is a placeholder for the process whose turn will be next allowed to enter the critical section.  As seen above, Process1 has been given priority over P0.&lt;br /&gt;
&lt;br /&gt;
To ensure mutual exclusion, the variable interested and turn are set to ensure only 1 can enter the critical section at a time.  To ensure Progress, once a processor has left the critical section the other processors can determine which processor is allowed into the critical section next.  To ensure bounded waiting, as seen with the above code, a process will wait no longer than 1 turn to enter the critical section as the variable turn=1 will be enabled.&lt;br /&gt;
&lt;br /&gt;
=Page tables=&lt;br /&gt;
An issue with multiprocessor systems is how to enter the critical section.  One software solution is to use Page tables to ensure mutual exclusion, progress, and bounded waiting which are the 3 criteria needed to be met&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;2body&amp;quot;&amp;gt;[[#2foot|[2]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Memory Coherence==&lt;br /&gt;
As with other forms of synchronization, page tables for multiprocessor systems must have strategies for handling data.  As discussed in Li and Hudaks article, there are two basic approaches for page synchronization, invalidation and write-broadcast.  In an invalidation approach, there is only 1 owner for each page, having either read or write access to the page.  In a write-broadcast, as the name implies, it broadcasts or writes all copies for the page data and returns the faulty instruction&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#3foot|[3]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
As mentioned in the invalidation approach, there must be an owner for the page.  There are two basic ownership approaches for page tables, fixed or dynamic.  In a fixed ownership approach, 1 processor always owns the same page.  Other processors who want read or write access to the page location must negotiate for the access.  For dynamic ownership, there are two subcategories, centralized or distributed management&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#3foot|[3]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Centralized Management==&lt;br /&gt;
In centralized management for dynamic pages, there is a single, central processor that maintains a page table which has a table for each page and each page has 3 fields: owner, copy set, and lock.  The owner field consists of the single processor which owns the page, which could also be thought as the most recent processor to have write access.  The copy set field has a list of all processors that have a copy of the page.  This field helps to avoid a broadcast.  The lock field is used for synchronizing requests&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#3foot|[3]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
==Distributed Management==&lt;br /&gt;
There are 2 schemes for Distributed Management: fixed and dynamic.  For a fixed distributed management, each processor in the system is given a predetermined subset of pages to manage.  A simple, straightforward distribution of responsibility is the divide pages evenly among the system, although there are other solutions which could be tailored to the applications needs&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#3foot|[3]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In a dynamic distributed management system, each processor keeps track of ownership of all pages within their local table.  Instead of the owner field in the Centralized Management scheme, instead there is a probOwner field which has the probable owner of the page for a page fault&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#3foot|[3]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;1foot&amp;quot;&amp;gt;[[#1body|1.]]&amp;lt;/span&amp;gt; http://en.wikipedia.org/wiki/Memory_coherence  &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;2foot&amp;quot;&amp;gt;[[#2body|2.]]&amp;lt;/span&amp;gt; http://en.wikipedia.org/wiki/Peterson%27s_algorithm  &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;3foot&amp;quot;&amp;gt;[[#3body|3.]]&amp;lt;/span&amp;gt; Li, K. and Hudak, P. Memory Coherence in Shared Virtual Memory Systems. ACM Transactions on Computer Systems, 7(4):321{359, November 1989.  &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;4foot&amp;quot;&amp;gt;[[#4body|4.]]&amp;lt;/span&amp;gt;http://web.sfc.keio.ac.jp/~rdv/keio/sfc/teaching/architecture/architecture-2007/lec08.html&lt;/div&gt;</summary>
		<author><name>Pmpatel</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_506_Spring_2011/ch7_jp&amp;diff=44591</id>
		<title>CSC/ECE 506 Spring 2011/ch7 jp</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_506_Spring_2011/ch7_jp&amp;diff=44591"/>
		<updated>2011-03-22T02:41:59Z</updated>

		<summary type="html">&lt;p&gt;Pmpatel: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Introduction=&lt;br /&gt;
&lt;br /&gt;
Shared memory architecture is one of the two major classes of large computer systems.  In a shared memory architecture, physical memory from all the processors is mapped into a single memory map.  All the processors can potentially access to all the memory on the system, although access time could be different (eg NUMA).  Different threads or processes can communicate by reading/writing to shared memory.&lt;br /&gt;
&lt;br /&gt;
==Advantages of shared memory system==&lt;br /&gt;
&lt;br /&gt;
* Shared memory parallel programs and multi-threaded programs will automatically run on shared memory system.&lt;br /&gt;
* Single OS runs on shared memory system which simplifies maintenance, memory management and scheduler tasks.&lt;br /&gt;
* Amount of total memory is large as it is simply sum of all memory of individual nodes.&lt;br /&gt;
* Communicating data between caches is faster than that in message passing model.&lt;br /&gt;
* Ability of finer granularity sharing compared to message passing which adds overhead of creating/sending messages for each bit of information.&lt;br /&gt;
* Common data types can be shared between different threads running on different processors. (eg. shared data which is Read Only)&lt;br /&gt;
&lt;br /&gt;
==Disadvantages of shared memory system==&lt;br /&gt;
&lt;br /&gt;
* Cost of providing shared memory grows super linearly with number of processors compared to message passing model which grows linearly.&lt;br /&gt;
&lt;br /&gt;
==Hardware Support ==&lt;br /&gt;
Shared memory architecture needs some hardware support for the implementation unlike a message passing model which can rely on software for send and receive messages.  Three things necessary with respect to hardware support for correct execution of a shared memory parallel program on a multiprocessor system are: &lt;br /&gt;
# Cache Coherence protocol&lt;br /&gt;
# Memory consistency model&lt;br /&gt;
# Hardware Synchronization&lt;br /&gt;
&lt;br /&gt;
=Cache Coherence Problem=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:sharedmem.jpg|thumbnail|right|600px|Shared Memory system with dedicated Cache for each processor&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#4foot|[4]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;]]	&lt;br /&gt;
&lt;br /&gt;
In a system with single processor (single core), maintaining cache coherency is simple and easy but in a multiprocessor system, it is not as simple.  Data can be present in any processors cache and protocol needs to ensure that the data is same in all caches.  If it cannot ensure that all the caches are same, then it needs to flag a cache line indicating that it is not updated.  &lt;br /&gt;
&lt;br /&gt;
In the figure shown here, this is a 4 processor shared memory system where each processor has its own cache.  Supposed processor P1 reads memory location M1 and stores it in its local cache.  Then, if P2 reads same location memory location then M1 gets stored in P2’s cache.  Now, if P1 changes value of M1, two copies of same data, residing in different caches will become different.  When P2 operates on M1, it uses the stale value of M1 that was stored in its cache.  It is responsibility of Cache Coherence Protocol to prevent this.  Hardware support is needed to provide a coherent view of data in multiple caches.  This is known as write propagation requirement.&lt;br /&gt;
&lt;br /&gt;
One may think that cache write policy can provide cache coherence but it is not true.  Cache write policy only controls how a change in value of cache is propagated to lower level cache or main memory.  It is not responsible for propagating changes to other caches.&lt;br /&gt;
&lt;br /&gt;
=Memory Consistency Problem=&lt;br /&gt;
&lt;br /&gt;
Memory consistency deals with the ordering of memory operations (load and store) to different memory locations.  In a single processor system, code will execute correctly if the compiler preservers the order of the access to synchronization variables and other dependent variables.  But in shared memory model with multiple processors, two threads could be access a shared data (something like a synchronization variable) and the output of the threads could change based on which thread can get to the shared data earlier.  If this happens, then the program output on uni-processor system and multi-processor program will be different.&lt;br /&gt;
&lt;br /&gt;
Maintaining program order is very important for memory consistency but it comes with performance degradation.  Various memory consistency models trades off performance to make programming easy.   &lt;br /&gt;
&lt;br /&gt;
=Peterson's Algorithm=&lt;br /&gt;
Peterson’s algorithm, also known as Peterson’s solution, is an algorithm that addresses the critical section problem by meeting the 3 criteria of the problem: mutual exclusion, progress, and bounded waiting&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;1body&amp;quot;&amp;gt;[[#1foot|[1]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 int turn;  // turn for execution&lt;br /&gt;
 int interested[2];   // the processors interested&lt;br /&gt;
 void enter_region(int process) &lt;br /&gt;
 { &lt;br /&gt;
   int otherProcess; &lt;br /&gt;
   otherProcess = 1 - process;    &lt;br /&gt;
   interested[process]=1;  &lt;br /&gt;
   turn = process;         &lt;br /&gt;
   while(turn == process &amp;amp;&amp;amp; interested[otherProcess] == 1)&lt;br /&gt;
      {&lt;br /&gt;
  	// busy wait&lt;br /&gt;
      }&lt;br /&gt;
 } &lt;br /&gt;
 void leave_region(int process) &lt;br /&gt;
 { &lt;br /&gt;
   interested[process] = 0; &lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
The algorithm uses two variables as seen above, interested and turn.  If a flag value for interested is set to 1, it indicates the process wants to enter the critical section.  The variable turn is a placeholder for the process whose turn will be next allowed to enter the critical section.  As seen above, Process1 has been given priority over P0.&lt;br /&gt;
&lt;br /&gt;
To ensure mutual exclusion, the variable interested and turn are set to ensure only 1 can enter the critical section at a time.  To ensure Progress, once a processor has left the critical section the other processors can determine which processor is allowed into the critical section next.  To ensure bounded waiting, as seen with the above code, a process will wait no longer than 1 turn to enter the critical section as the variable turn=1 will be enabled.&lt;br /&gt;
&lt;br /&gt;
=Page tables=&lt;br /&gt;
An issue with multiprocessor systems is how to enter the critical section.  One software solution is to use Page tables to ensure mutual exclusion, progress, and bounded waiting which are the 3 criteria needed to be met&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;2body&amp;quot;&amp;gt;[[#2foot|[2]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Memory Coherence==&lt;br /&gt;
As with other forms of synchronization, page tables for multiprocessor systems must have strategies for handling data.  As discussed in Li and Hudaks article, there are two basic approaches for page synchronization, invalidation and write-broadcast.  In an invalidation approach, there is only 1 owner for each page, having either read or write access to the page.  In a write-broadcast, as the name implies, it broadcasts or writes all copies for the page data and returns the faulty instruction&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#3foot|[3]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
As mentioned in the invalidation approach, there must be an owner for the page.  There are two basic ownership approaches for page tables, fixed or dynamic.  In a fixed ownership approach, 1 processor always owns the same page.  Other processors who want read or write access to the page location must negotiate for the access.  For dynamic ownership, there are two subcategories, centralized or distributed management&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#3foot|[3]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Centralized Management==&lt;br /&gt;
In centralized management for dynamic pages, there is a single, central processor that maintains a page table which has a table for each page and each page has 3 fields: owner, copy set, and lock.  The owner field consists of the single processor which owns the page, which could also be thought as the most recent processor to have write access.  The copy set field has a list of all processors that have a copy of the page.  This field helps to avoid a broadcast.  The lock field is used for synchronizing requests&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#3foot|[3]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
==Distributed Management==&lt;br /&gt;
There are 2 schemes for Distributed Management: fixed and dynamic.  For a fixed distributed management, each processor in the system is given a predetermined subset of pages to manage.  A simple, straightforward distribution of responsibility is the divide pages evenly among the system, although there are other solutions which could be tailored to the applications needs&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#3foot|[3]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In a dynamic distributed management system, each processor keeps track of ownership of all pages within their local table.  Instead of the owner field in the Centralized Management scheme, instead there is a probOwner field which has the probable owner of the page for a page fault&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#3foot|[3]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;1foot&amp;quot;&amp;gt;[[#1body|1.]]&amp;lt;/span&amp;gt; http://en.wikipedia.org/wiki/Memory_coherence  &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;2foot&amp;quot;&amp;gt;[[#2body|2.]]&amp;lt;/span&amp;gt; http://en.wikipedia.org/wiki/Peterson%27s_algorithm  &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;3foot&amp;quot;&amp;gt;[[#3body|3.]]&amp;lt;/span&amp;gt; Li, K. and Hudak, P. Memory Coherence in Shared Virtual Memory Systems. ACM Transactions on Computer Systems, 7(4):321{359, November 1989.  &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;4foot&amp;quot;&amp;gt;[[#4body|4.]]&amp;lt;/span&amp;gt;http://web.sfc.keio.ac.jp/~rdv/keio/sfc/teaching/architecture/architecture-2007/lec08.html&lt;/div&gt;</summary>
		<author><name>Pmpatel</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_506_Spring_2011/ch7_jp&amp;diff=44590</id>
		<title>CSC/ECE 506 Spring 2011/ch7 jp</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_506_Spring_2011/ch7_jp&amp;diff=44590"/>
		<updated>2011-03-22T02:34:31Z</updated>

		<summary type="html">&lt;p&gt;Pmpatel: /* Peterson's Algorithm */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Introduction=&lt;br /&gt;
&lt;br /&gt;
Shared memory architecture is one of the two major classes of large computer systems.  In a shared memory architecture, physical memory from all the processors is mapped into a single memory map.  All the processors can potentially access to all the memory on the system, although access time could be different (eg NUMA).&lt;br /&gt;
&lt;br /&gt;
==Advantages of shared memory system==&lt;br /&gt;
&lt;br /&gt;
* Shared memory parallel programs and multi-threaded programs will automatically run on shared memory system.&lt;br /&gt;
* Single OS runs on shared memory system which simplifies maintenance, memory management and scheduler tasks.&lt;br /&gt;
* Amount of total memory is large as it is simply sum of all memory of individual nodes.&lt;br /&gt;
* Communicating data between caches is faster than that in message passing model.&lt;br /&gt;
* Ability of finer granularity sharing compared to message passing which adds overhead of creating/sending messages for each bit of information.&lt;br /&gt;
* Common data types can be shared between different threads running on different processors. (eg. shared data which is Read Only)&lt;br /&gt;
&lt;br /&gt;
==Disadvantages of shared memory system==&lt;br /&gt;
&lt;br /&gt;
* Cost of providing shared memory grows super linearly with number of processors compared to message passing model which grows linearly.&lt;br /&gt;
&lt;br /&gt;
==Hardware Support ==&lt;br /&gt;
Shared memory architecture needs some hardware support for the implementation unlike a message passing model which can rely on software for send and receive messages.  Three things necessary with respect to hardware support for correct execution of a shared memory parallel program on a multiprocessor system are: &lt;br /&gt;
# Cache Coherence protocol&lt;br /&gt;
# Memory consistency model&lt;br /&gt;
# Hardware Synchronization&lt;br /&gt;
&lt;br /&gt;
=Cache Coherence Problem=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:sharedmem.jpg|thumbnail|right|600px|Shared Memory system with dedicated Cache for each processor&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#4foot|[4]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;]]	&lt;br /&gt;
&lt;br /&gt;
In a system with single processor (single core), maintaining cache coherency is simple and easy but in a multiprocessor system, it is not as simple.  Data can be present in any processors cache and protocol needs to ensure that the data is same in all caches.  If it cannot ensure that all the caches are same, then it needs to flag a cache line indicating that it is not updated.  &lt;br /&gt;
&lt;br /&gt;
In the figure shown here, this is a 4 processor shared memory system where each processor has its own cache.  Supposed processor P1 reads memory location M1 and stores it in its local cache.  Then, if P2 reads same location memory location then M1 gets stored in P2’s cache.  Now, if P1 changes value of M1, two copies of same data, residing in different caches will become different.  When P2 operates on M1, it uses the stale value of M1 that was stored in its cache.  It is responsibility of Cache Coherence Protocol to prevent this.  Hardware support is needed to provide a coherent view of data in multiple caches.  This is known as write propagation requirement.&lt;br /&gt;
&lt;br /&gt;
One may think that cache write policy can provide cache coherence but it is not true.  Cache write policy only controls how a change in value of cache is propagated to lower level cache or main memory.  It is not responsible for propagating changes to other caches.&lt;br /&gt;
&lt;br /&gt;
=Memory Consistency Problem=&lt;br /&gt;
&lt;br /&gt;
Memory consistency deals with the ordering of memory operations (load and store) to different memory locations.  In a single processor system, code will execute correctly if the compiler preservers the order of the access to synchronization variables and other dependent variables.  But in shared memory model with multiple processors, two threads could be access a shared data (something like a synchronization variable) and the output of the threads could change based on which thread can get to the shared data earlier.  If this happens, then the program output on uni-processor system and multi-processor program will be different.&lt;br /&gt;
&lt;br /&gt;
Maintaining program order is very important for memory consistency but it comes with performance degradation.  Various memory consistency models trades off performance to make programming easy.   &lt;br /&gt;
&lt;br /&gt;
=Peterson's Algorithm=&lt;br /&gt;
Peterson’s algorithm, also known as Peterson’s solution, is an algorithm that addresses the critical section problem by meeting the 3 criteria of the problem: mutual exclusion, progress, and bounded waiting&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;1body&amp;quot;&amp;gt;[[#1foot|[1]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 int turn;  // turn for execution&lt;br /&gt;
 int interested[2];   // the processors interested&lt;br /&gt;
 void enter_region(int process) &lt;br /&gt;
 { &lt;br /&gt;
   int otherProcess; &lt;br /&gt;
   otherProcess = 1 - process;    &lt;br /&gt;
   interested[process]=1;  &lt;br /&gt;
   turn = process;         &lt;br /&gt;
   while(turn == process &amp;amp;&amp;amp; interested[otherProcess] == 1)&lt;br /&gt;
      {&lt;br /&gt;
  	// busy wait&lt;br /&gt;
      }&lt;br /&gt;
 } &lt;br /&gt;
 void leave_region(int process) &lt;br /&gt;
 { &lt;br /&gt;
   interested[process] = 0; &lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
The algorithm uses two variables as seen above, interested and turn.  If a flag value for interested is set to 1, it indicates the process wants to enter the critical section.  The variable turn is a placeholder for the process whose turn will be next allowed to enter the critical section.  As seen above, Process1 has been given priority over P0.&lt;br /&gt;
&lt;br /&gt;
To ensure mutual exclusion, the variable interested and turn are set to ensure only 1 can enter the critical section at a time.  To ensure Progress, once a processor has left the critical section the other processors can determine which processor is allowed into the critical section next.  To ensure bounded waiting, as seen with the above code, a process will wait no longer than 1 turn to enter the critical section as the variable turn=1 will be enabled.&lt;br /&gt;
&lt;br /&gt;
=Page tables=&lt;br /&gt;
An issue with multiprocessor systems is how to enter the critical section.  One software solution is to use Page tables to ensure mutual exclusion, progress, and bounded waiting which are the 3 criteria needed to be met&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;2body&amp;quot;&amp;gt;[[#2foot|[2]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Memory Coherence==&lt;br /&gt;
As with other forms of synchronization, page tables for multiprocessor systems must have strategies for handling data.  As discussed in Li and Hudaks article, there are two basic approaches for page synchronization, invalidation and write-broadcast.  In an invalidation approach, there is only 1 owner for each page, having either read or write access to the page.  In a write-broadcast, as the name implies, it broadcasts or writes all copies for the page data and returns the faulty instruction&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#3foot|[3]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
As mentioned in the invalidation approach, there must be an owner for the page.  There are two basic ownership approaches for page tables, fixed or dynamic.  In a fixed ownership approach, 1 processor always owns the same page.  Other processors who want read or write access to the page location must negotiate for the access.  For dynamic ownership, there are two subcategories, centralized or distributed management&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#3foot|[3]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Centralized Management==&lt;br /&gt;
In centralized management for dynamic pages, there is a single, central processor that maintains a page table which has a table for each page and each page has 3 fields: owner, copy set, and lock.  The owner field consists of the single processor which owns the page, which could also be thought as the most recent processor to have write access.  The copy set field has a list of all processors that have a copy of the page.  This field helps to avoid a broadcast.  The lock field is used for synchronizing requests&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#3foot|[3]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
==Distributed Management==&lt;br /&gt;
There are 2 schemes for Distributed Management: fixed and dynamic.  For a fixed distributed management, each processor in the system is given a predetermined subset of pages to manage.  A simple, straightforward distribution of responsibility is the divide pages evenly among the system, although there are other solutions which could be tailored to the applications needs&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#3foot|[3]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In a dynamic distributed management system, each processor keeps track of ownership of all pages within their local table.  Instead of the owner field in the Centralized Management scheme, instead there is a probOwner field which has the probable owner of the page for a page fault&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#3foot|[3]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;1foot&amp;quot;&amp;gt;[[#1body|1.]]&amp;lt;/span&amp;gt; http://en.wikipedia.org/wiki/Memory_coherence  &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;2foot&amp;quot;&amp;gt;[[#2body|2.]]&amp;lt;/span&amp;gt; http://en.wikipedia.org/wiki/Peterson%27s_algorithm  &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;3foot&amp;quot;&amp;gt;[[#3body|3.]]&amp;lt;/span&amp;gt; Li, K. and Hudak, P. Memory Coherence in Shared Virtual Memory Systems. ACM Transactions on Computer Systems, 7(4):321{359, November 1989.  &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;4foot&amp;quot;&amp;gt;[[#4body|4.]]&amp;lt;/span&amp;gt;http://web.sfc.keio.ac.jp/~rdv/keio/sfc/teaching/architecture/architecture-2007/lec08.html&lt;/div&gt;</summary>
		<author><name>Pmpatel</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_506_Spring_2011/ch7_jp&amp;diff=44589</id>
		<title>CSC/ECE 506 Spring 2011/ch7 jp</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_506_Spring_2011/ch7_jp&amp;diff=44589"/>
		<updated>2011-03-22T02:31:09Z</updated>

		<summary type="html">&lt;p&gt;Pmpatel: /* Cache Coherence Problem */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Introduction=&lt;br /&gt;
&lt;br /&gt;
Shared memory architecture is one of the two major classes of large computer systems.  In a shared memory architecture, physical memory from all the processors is mapped into a single memory map.  All the processors can potentially access to all the memory on the system, although access time could be different (eg NUMA).&lt;br /&gt;
&lt;br /&gt;
==Advantages of shared memory system==&lt;br /&gt;
&lt;br /&gt;
* Shared memory parallel programs and multi-threaded programs will automatically run on shared memory system.&lt;br /&gt;
* Single OS runs on shared memory system which simplifies maintenance, memory management and scheduler tasks.&lt;br /&gt;
* Amount of total memory is large as it is simply sum of all memory of individual nodes.&lt;br /&gt;
* Communicating data between caches is faster than that in message passing model.&lt;br /&gt;
* Ability of finer granularity sharing compared to message passing which adds overhead of creating/sending messages for each bit of information.&lt;br /&gt;
* Common data types can be shared between different threads running on different processors. (eg. shared data which is Read Only)&lt;br /&gt;
&lt;br /&gt;
==Disadvantages of shared memory system==&lt;br /&gt;
&lt;br /&gt;
* Cost of providing shared memory grows super linearly with number of processors compared to message passing model which grows linearly.&lt;br /&gt;
&lt;br /&gt;
==Hardware Support ==&lt;br /&gt;
Shared memory architecture needs some hardware support for the implementation unlike a message passing model which can rely on software for send and receive messages.  Three things necessary with respect to hardware support for correct execution of a shared memory parallel program on a multiprocessor system are: &lt;br /&gt;
# Cache Coherence protocol&lt;br /&gt;
# Memory consistency model&lt;br /&gt;
# Hardware Synchronization&lt;br /&gt;
&lt;br /&gt;
=Cache Coherence Problem=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:sharedmem.jpg|thumbnail|right|600px|Shared Memory system with dedicated Cache for each processor&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#4foot|[4]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;]]	&lt;br /&gt;
&lt;br /&gt;
In a system with single processor (single core), maintaining cache coherency is simple and easy but in a multiprocessor system, it is not as simple.  Data can be present in any processors cache and protocol needs to ensure that the data is same in all caches.  If it cannot ensure that all the caches are same, then it needs to flag a cache line indicating that it is not updated.  &lt;br /&gt;
&lt;br /&gt;
In the figure shown here, this is a 4 processor shared memory system where each processor has its own cache.  Supposed processor P1 reads memory location M1 and stores it in its local cache.  Then, if P2 reads same location memory location then M1 gets stored in P2’s cache.  Now, if P1 changes value of M1, two copies of same data, residing in different caches will become different.  When P2 operates on M1, it uses the stale value of M1 that was stored in its cache.  It is responsibility of Cache Coherence Protocol to prevent this.  Hardware support is needed to provide a coherent view of data in multiple caches.  This is known as write propagation requirement.&lt;br /&gt;
&lt;br /&gt;
One may think that cache write policy can provide cache coherence but it is not true.  Cache write policy only controls how a change in value of cache is propagated to lower level cache or main memory.  It is not responsible for propagating changes to other caches.&lt;br /&gt;
&lt;br /&gt;
=Memory Consistency Problem=&lt;br /&gt;
&lt;br /&gt;
Memory consistency deals with the ordering of memory operations (load and store) to different memory locations.  In a single processor system, code will execute correctly if the compiler preservers the order of the access to synchronization variables and other dependent variables.  But in shared memory model with multiple processors, two threads could be access a shared data (something like a synchronization variable) and the output of the threads could change based on which thread can get to the shared data earlier.  If this happens, then the program output on uni-processor system and multi-processor program will be different.&lt;br /&gt;
&lt;br /&gt;
Maintaining program order is very important for memory consistency but it comes with performance degradation.  Various memory consistency models trades off performance to make programming easy.   &lt;br /&gt;
&lt;br /&gt;
=Peterson's Algorithm=&lt;br /&gt;
Peterson’s algorithm, also known as Peterson’s solution, is an algorithm that addresses the critical section problem by meeting the 3 criteria of the problem: mutual exclusion, progress, and bounded waiting&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;1body&amp;quot;&amp;gt;[[#1foot|[1]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 int turn;  // turn for execution&lt;br /&gt;
 int interested[2];   // the processors interested&lt;br /&gt;
 void enter_region(int process) &lt;br /&gt;
 { &lt;br /&gt;
   int otherProcess; &lt;br /&gt;
   otherProcess = 1 - process;    &lt;br /&gt;
   interested[process]=1;  &lt;br /&gt;
   turn = process;         &lt;br /&gt;
   while(turn == process &amp;amp;&amp;amp; interested[otherProcess] == 1)&lt;br /&gt;
      {&lt;br /&gt;
  	// busy wait&lt;br /&gt;
      }&lt;br /&gt;
 } &lt;br /&gt;
 void leave_region(int process) &lt;br /&gt;
 { &lt;br /&gt;
   interested[process] = 0; &lt;br /&gt;
 }&lt;br /&gt;
The algorithm uses two variables as seen above, interested and turn.  If a flag value for interested is set to 1, it indicates the process wants to enter the critical section.  The variable turn is a placeholder for the process whose turn will be next allowed to enter the critical section.  As seen above, Process1 has been given priority over P0.&lt;br /&gt;
&lt;br /&gt;
To ensure mutual exclusion, the variable interested and turn are set to ensure only 1 can enter the critical section at a time.  To ensure Progress, once a processor has left the critical section the other processors can determine which processor is allowed into the critical section next.  To ensure bounded waiting, as seen with the above code, a process will wait no longer than 1 turn to enter the critical section as the variable turn=1 will be enabled.&lt;br /&gt;
&lt;br /&gt;
=Page tables=&lt;br /&gt;
An issue with multiprocessor systems is how to enter the critical section.  One software solution is to use Page tables to ensure mutual exclusion, progress, and bounded waiting which are the 3 criteria needed to be met&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;2body&amp;quot;&amp;gt;[[#2foot|[2]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Memory Coherence==&lt;br /&gt;
As with other forms of synchronization, page tables for multiprocessor systems must have strategies for handling data.  As discussed in Li and Hudaks article, there are two basic approaches for page synchronization, invalidation and write-broadcast.  In an invalidation approach, there is only 1 owner for each page, having either read or write access to the page.  In a write-broadcast, as the name implies, it broadcasts or writes all copies for the page data and returns the faulty instruction&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#3foot|[3]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
As mentioned in the invalidation approach, there must be an owner for the page.  There are two basic ownership approaches for page tables, fixed or dynamic.  In a fixed ownership approach, 1 processor always owns the same page.  Other processors who want read or write access to the page location must negotiate for the access.  For dynamic ownership, there are two subcategories, centralized or distributed management&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#3foot|[3]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Centralized Management==&lt;br /&gt;
In centralized management for dynamic pages, there is a single, central processor that maintains a page table which has a table for each page and each page has 3 fields: owner, copy set, and lock.  The owner field consists of the single processor which owns the page, which could also be thought as the most recent processor to have write access.  The copy set field has a list of all processors that have a copy of the page.  This field helps to avoid a broadcast.  The lock field is used for synchronizing requests&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#3foot|[3]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
==Distributed Management==&lt;br /&gt;
There are 2 schemes for Distributed Management: fixed and dynamic.  For a fixed distributed management, each processor in the system is given a predetermined subset of pages to manage.  A simple, straightforward distribution of responsibility is the divide pages evenly among the system, although there are other solutions which could be tailored to the applications needs&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#3foot|[3]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In a dynamic distributed management system, each processor keeps track of ownership of all pages within their local table.  Instead of the owner field in the Centralized Management scheme, instead there is a probOwner field which has the probable owner of the page for a page fault&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#3foot|[3]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;1foot&amp;quot;&amp;gt;[[#1body|1.]]&amp;lt;/span&amp;gt; http://en.wikipedia.org/wiki/Memory_coherence  &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;2foot&amp;quot;&amp;gt;[[#2body|2.]]&amp;lt;/span&amp;gt; http://en.wikipedia.org/wiki/Peterson%27s_algorithm  &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;3foot&amp;quot;&amp;gt;[[#3body|3.]]&amp;lt;/span&amp;gt; Li, K. and Hudak, P. Memory Coherence in Shared Virtual Memory Systems. ACM Transactions on Computer Systems, 7(4):321{359, November 1989.  &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;4foot&amp;quot;&amp;gt;[[#4body|4.]]&amp;lt;/span&amp;gt;http://web.sfc.keio.ac.jp/~rdv/keio/sfc/teaching/architecture/architecture-2007/lec08.html&lt;/div&gt;</summary>
		<author><name>Pmpatel</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_506_Spring_2011/ch7_jp&amp;diff=44588</id>
		<title>CSC/ECE 506 Spring 2011/ch7 jp</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_506_Spring_2011/ch7_jp&amp;diff=44588"/>
		<updated>2011-03-22T02:30:48Z</updated>

		<summary type="html">&lt;p&gt;Pmpatel: /* Cache Coherence Problem */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Introduction=&lt;br /&gt;
&lt;br /&gt;
Shared memory architecture is one of the two major classes of large computer systems.  In a shared memory architecture, physical memory from all the processors is mapped into a single memory map.  All the processors can potentially access to all the memory on the system, although access time could be different (eg NUMA).&lt;br /&gt;
&lt;br /&gt;
==Advantages of shared memory system==&lt;br /&gt;
&lt;br /&gt;
* Shared memory parallel programs and multi-threaded programs will automatically run on shared memory system.&lt;br /&gt;
* Single OS runs on shared memory system which simplifies maintenance, memory management and scheduler tasks.&lt;br /&gt;
* Amount of total memory is large as it is simply sum of all memory of individual nodes.&lt;br /&gt;
* Communicating data between caches is faster than that in message passing model.&lt;br /&gt;
* Ability of finer granularity sharing compared to message passing which adds overhead of creating/sending messages for each bit of information.&lt;br /&gt;
* Common data types can be shared between different threads running on different processors. (eg. shared data which is Read Only)&lt;br /&gt;
&lt;br /&gt;
==Disadvantages of shared memory system==&lt;br /&gt;
&lt;br /&gt;
* Cost of providing shared memory grows super linearly with number of processors compared to message passing model which grows linearly.&lt;br /&gt;
&lt;br /&gt;
==Hardware Support ==&lt;br /&gt;
Shared memory architecture needs some hardware support for the implementation unlike a message passing model which can rely on software for send and receive messages.  Three things necessary with respect to hardware support for correct execution of a shared memory parallel program on a multiprocessor system are: &lt;br /&gt;
# Cache Coherence protocol&lt;br /&gt;
# Memory consistency model&lt;br /&gt;
# Hardware Synchronization&lt;br /&gt;
&lt;br /&gt;
=Cache Coherence Problem=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:sharedmem.jpg|thumbnail|right|700px|Shared Memory system with dedicated Cache for each processor&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#4foot|[4]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;]]	&lt;br /&gt;
&lt;br /&gt;
In a system with single processor (single core), maintaining cache coherency is simple and easy but in a multiprocessor system, it is not as simple.  Data can be present in any processors cache and protocol needs to ensure that the data is same in all caches.  If it cannot ensure that all the caches are same, then it needs to flag a cache line indicating that it is not updated.  &lt;br /&gt;
&lt;br /&gt;
In the figure shown here, this is a 4 processor shared memory system where each processor has its own cache.  Supposed processor P1 reads memory location M1 and stores it in its local cache.  Then, if P2 reads same location memory location then M1 gets stored in P2’s cache.  Now, if P1 changes value of M1, two copies of same data, residing in different caches will become different.  When P2 operates on M1, it uses the stale value of M1 that was stored in its cache.  It is responsibility of Cache Coherence Protocol to prevent this.  Hardware support is needed to provide a coherent view of data in multiple caches.  This is known as write propagation requirement.&lt;br /&gt;
&lt;br /&gt;
One may think that cache write policy can provide cache coherence but it is not true.  Cache write policy only controls how a change in value of cache is propagated to lower level cache or main memory.  It is not responsible for propagating changes to other caches.&lt;br /&gt;
&lt;br /&gt;
=Memory Consistency Problem=&lt;br /&gt;
&lt;br /&gt;
Memory consistency deals with the ordering of memory operations (load and store) to different memory locations.  In a single processor system, code will execute correctly if the compiler preservers the order of the access to synchronization variables and other dependent variables.  But in shared memory model with multiple processors, two threads could be access a shared data (something like a synchronization variable) and the output of the threads could change based on which thread can get to the shared data earlier.  If this happens, then the program output on uni-processor system and multi-processor program will be different.&lt;br /&gt;
&lt;br /&gt;
Maintaining program order is very important for memory consistency but it comes with performance degradation.  Various memory consistency models trades off performance to make programming easy.   &lt;br /&gt;
&lt;br /&gt;
=Peterson's Algorithm=&lt;br /&gt;
Peterson’s algorithm, also known as Peterson’s solution, is an algorithm that addresses the critical section problem by meeting the 3 criteria of the problem: mutual exclusion, progress, and bounded waiting&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;1body&amp;quot;&amp;gt;[[#1foot|[1]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 int turn;  // turn for execution&lt;br /&gt;
 int interested[2];   // the processors interested&lt;br /&gt;
 void enter_region(int process) &lt;br /&gt;
 { &lt;br /&gt;
   int otherProcess; &lt;br /&gt;
   otherProcess = 1 - process;    &lt;br /&gt;
   interested[process]=1;  &lt;br /&gt;
   turn = process;         &lt;br /&gt;
   while(turn == process &amp;amp;&amp;amp; interested[otherProcess] == 1)&lt;br /&gt;
      {&lt;br /&gt;
  	// busy wait&lt;br /&gt;
      }&lt;br /&gt;
 } &lt;br /&gt;
 void leave_region(int process) &lt;br /&gt;
 { &lt;br /&gt;
   interested[process] = 0; &lt;br /&gt;
 }&lt;br /&gt;
The algorithm uses two variables as seen above, interested and turn.  If a flag value for interested is set to 1, it indicates the process wants to enter the critical section.  The variable turn is a placeholder for the process whose turn will be next allowed to enter the critical section.  As seen above, Process1 has been given priority over P0.&lt;br /&gt;
&lt;br /&gt;
To ensure mutual exclusion, the variable interested and turn are set to ensure only 1 can enter the critical section at a time.  To ensure Progress, once a processor has left the critical section the other processors can determine which processor is allowed into the critical section next.  To ensure bounded waiting, as seen with the above code, a process will wait no longer than 1 turn to enter the critical section as the variable turn=1 will be enabled.&lt;br /&gt;
&lt;br /&gt;
=Page tables=&lt;br /&gt;
An issue with multiprocessor systems is how to enter the critical section.  One software solution is to use Page tables to ensure mutual exclusion, progress, and bounded waiting which are the 3 criteria needed to be met&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;2body&amp;quot;&amp;gt;[[#2foot|[2]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Memory Coherence==&lt;br /&gt;
As with other forms of synchronization, page tables for multiprocessor systems must have strategies for handling data.  As discussed in Li and Hudaks article, there are two basic approaches for page synchronization, invalidation and write-broadcast.  In an invalidation approach, there is only 1 owner for each page, having either read or write access to the page.  In a write-broadcast, as the name implies, it broadcasts or writes all copies for the page data and returns the faulty instruction&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#3foot|[3]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
As mentioned in the invalidation approach, there must be an owner for the page.  There are two basic ownership approaches for page tables, fixed or dynamic.  In a fixed ownership approach, 1 processor always owns the same page.  Other processors who want read or write access to the page location must negotiate for the access.  For dynamic ownership, there are two subcategories, centralized or distributed management&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#3foot|[3]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Centralized Management==&lt;br /&gt;
In centralized management for dynamic pages, there is a single, central processor that maintains a page table which has a table for each page and each page has 3 fields: owner, copy set, and lock.  The owner field consists of the single processor which owns the page, which could also be thought as the most recent processor to have write access.  The copy set field has a list of all processors that have a copy of the page.  This field helps to avoid a broadcast.  The lock field is used for synchronizing requests&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#3foot|[3]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
==Distributed Management==&lt;br /&gt;
There are 2 schemes for Distributed Management: fixed and dynamic.  For a fixed distributed management, each processor in the system is given a predetermined subset of pages to manage.  A simple, straightforward distribution of responsibility is the divide pages evenly among the system, although there are other solutions which could be tailored to the applications needs&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#3foot|[3]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In a dynamic distributed management system, each processor keeps track of ownership of all pages within their local table.  Instead of the owner field in the Centralized Management scheme, instead there is a probOwner field which has the probable owner of the page for a page fault&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#3foot|[3]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;1foot&amp;quot;&amp;gt;[[#1body|1.]]&amp;lt;/span&amp;gt; http://en.wikipedia.org/wiki/Memory_coherence  &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;2foot&amp;quot;&amp;gt;[[#2body|2.]]&amp;lt;/span&amp;gt; http://en.wikipedia.org/wiki/Peterson%27s_algorithm  &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;3foot&amp;quot;&amp;gt;[[#3body|3.]]&amp;lt;/span&amp;gt; Li, K. and Hudak, P. Memory Coherence in Shared Virtual Memory Systems. ACM Transactions on Computer Systems, 7(4):321{359, November 1989.  &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;4foot&amp;quot;&amp;gt;[[#4body|4.]]&amp;lt;/span&amp;gt;http://web.sfc.keio.ac.jp/~rdv/keio/sfc/teaching/architecture/architecture-2007/lec08.html&lt;/div&gt;</summary>
		<author><name>Pmpatel</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_506_Spring_2011/ch7_jp&amp;diff=44587</id>
		<title>CSC/ECE 506 Spring 2011/ch7 jp</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_506_Spring_2011/ch7_jp&amp;diff=44587"/>
		<updated>2011-03-22T02:29:11Z</updated>

		<summary type="html">&lt;p&gt;Pmpatel: /* Introduction */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Introduction=&lt;br /&gt;
&lt;br /&gt;
Shared memory architecture is one of the two major classes of large computer systems.  In a shared memory architecture, physical memory from all the processors is mapped into a single memory map.  All the processors can potentially access to all the memory on the system, although access time could be different (eg NUMA).&lt;br /&gt;
&lt;br /&gt;
==Advantages of shared memory system==&lt;br /&gt;
&lt;br /&gt;
* Shared memory parallel programs and multi-threaded programs will automatically run on shared memory system.&lt;br /&gt;
* Single OS runs on shared memory system which simplifies maintenance, memory management and scheduler tasks.&lt;br /&gt;
* Amount of total memory is large as it is simply sum of all memory of individual nodes.&lt;br /&gt;
* Communicating data between caches is faster than that in message passing model.&lt;br /&gt;
* Ability of finer granularity sharing compared to message passing which adds overhead of creating/sending messages for each bit of information.&lt;br /&gt;
* Common data types can be shared between different threads running on different processors. (eg. shared data which is Read Only)&lt;br /&gt;
&lt;br /&gt;
==Disadvantages of shared memory system==&lt;br /&gt;
&lt;br /&gt;
* Cost of providing shared memory grows super linearly with number of processors compared to message passing model which grows linearly.&lt;br /&gt;
&lt;br /&gt;
==Hardware Support ==&lt;br /&gt;
Shared memory architecture needs some hardware support for the implementation unlike a message passing model which can rely on software for send and receive messages.  Three things necessary with respect to hardware support for correct execution of a shared memory parallel program on a multiprocessor system are: &lt;br /&gt;
# Cache Coherence protocol&lt;br /&gt;
# Memory consistency model&lt;br /&gt;
# Hardware Synchronization&lt;br /&gt;
&lt;br /&gt;
=Cache Coherence Problem=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:sharedmem.jpg|thumbnail|right|500px|Shared Memory&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#4foot|[4]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;]]	&lt;br /&gt;
&lt;br /&gt;
In a system with single processor (single core), maintaining cache coherency is simple and easy but in a multiprocessor system, it is not as simple.  Data can be present in any processors cache and protocol needs to ensure that the data is same in all caches.  If it cannot ensure that all the caches are same, then it needs to flag a cache line indicating that it is not updated.  &lt;br /&gt;
&lt;br /&gt;
In the figure shown here, this is a 4 processor shared memory system where each processor has its own cache.  Supposed processor P1 reads memory location M1 and stores it in its local cache.  Then, if P2 reads same location memory location then M1 gets stored in P2’s cache.  Now, if P1 changes value of M1, two copies of same data, residing in different caches will become different.  When P2 operates on M1, it uses the stale value of M1 that was stored in its cache.  It is responsibility of Cache Coherence Protocol to prevent this.  Hardware support is needed to provide a coherent view of data in multiple caches.  This is known as write propagation requirement.&lt;br /&gt;
&lt;br /&gt;
One may think that cache write policy can provide cache coherence but it is not true.  Cache write policy only controls how a change in value of cache is propagated to lower level cache or main memory.  It is not responsible for propagating changes to other caches.&lt;br /&gt;
&lt;br /&gt;
=Memory Consistency Problem=&lt;br /&gt;
&lt;br /&gt;
Memory consistency deals with the ordering of memory operations (load and store) to different memory locations.  In a single processor system, code will execute correctly if the compiler preservers the order of the access to synchronization variables and other dependent variables.  But in shared memory model with multiple processors, two threads could be access a shared data (something like a synchronization variable) and the output of the threads could change based on which thread can get to the shared data earlier.  If this happens, then the program output on uni-processor system and multi-processor program will be different.&lt;br /&gt;
&lt;br /&gt;
Maintaining program order is very important for memory consistency but it comes with performance degradation.  Various memory consistency models trades off performance to make programming easy.   &lt;br /&gt;
&lt;br /&gt;
=Peterson's Algorithm=&lt;br /&gt;
Peterson’s algorithm, also known as Peterson’s solution, is an algorithm that addresses the critical section problem by meeting the 3 criteria of the problem: mutual exclusion, progress, and bounded waiting&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;1body&amp;quot;&amp;gt;[[#1foot|[1]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 int turn;  // turn for execution&lt;br /&gt;
 int interested[2];   // the processors interested&lt;br /&gt;
 void enter_region(int process) &lt;br /&gt;
 { &lt;br /&gt;
   int otherProcess; &lt;br /&gt;
   otherProcess = 1 - process;    &lt;br /&gt;
   interested[process]=1;  &lt;br /&gt;
   turn = process;         &lt;br /&gt;
   while(turn == process &amp;amp;&amp;amp; interested[otherProcess] == 1)&lt;br /&gt;
      {&lt;br /&gt;
  	// busy wait&lt;br /&gt;
      }&lt;br /&gt;
 } &lt;br /&gt;
 void leave_region(int process) &lt;br /&gt;
 { &lt;br /&gt;
   interested[process] = 0; &lt;br /&gt;
 }&lt;br /&gt;
The algorithm uses two variables as seen above, interested and turn.  If a flag value for interested is set to 1, it indicates the process wants to enter the critical section.  The variable turn is a placeholder for the process whose turn will be next allowed to enter the critical section.  As seen above, Process1 has been given priority over P0.&lt;br /&gt;
&lt;br /&gt;
To ensure mutual exclusion, the variable interested and turn are set to ensure only 1 can enter the critical section at a time.  To ensure Progress, once a processor has left the critical section the other processors can determine which processor is allowed into the critical section next.  To ensure bounded waiting, as seen with the above code, a process will wait no longer than 1 turn to enter the critical section as the variable turn=1 will be enabled.&lt;br /&gt;
&lt;br /&gt;
=Page tables=&lt;br /&gt;
An issue with multiprocessor systems is how to enter the critical section.  One software solution is to use Page tables to ensure mutual exclusion, progress, and bounded waiting which are the 3 criteria needed to be met&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;2body&amp;quot;&amp;gt;[[#2foot|[2]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Memory Coherence==&lt;br /&gt;
As with other forms of synchronization, page tables for multiprocessor systems must have strategies for handling data.  As discussed in Li and Hudaks article, there are two basic approaches for page synchronization, invalidation and write-broadcast.  In an invalidation approach, there is only 1 owner for each page, having either read or write access to the page.  In a write-broadcast, as the name implies, it broadcasts or writes all copies for the page data and returns the faulty instruction&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#3foot|[3]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
As mentioned in the invalidation approach, there must be an owner for the page.  There are two basic ownership approaches for page tables, fixed or dynamic.  In a fixed ownership approach, 1 processor always owns the same page.  Other processors who want read or write access to the page location must negotiate for the access.  For dynamic ownership, there are two subcategories, centralized or distributed management&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#3foot|[3]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Centralized Management==&lt;br /&gt;
In centralized management for dynamic pages, there is a single, central processor that maintains a page table which has a table for each page and each page has 3 fields: owner, copy set, and lock.  The owner field consists of the single processor which owns the page, which could also be thought as the most recent processor to have write access.  The copy set field has a list of all processors that have a copy of the page.  This field helps to avoid a broadcast.  The lock field is used for synchronizing requests&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#3foot|[3]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
==Distributed Management==&lt;br /&gt;
There are 2 schemes for Distributed Management: fixed and dynamic.  For a fixed distributed management, each processor in the system is given a predetermined subset of pages to manage.  A simple, straightforward distribution of responsibility is the divide pages evenly among the system, although there are other solutions which could be tailored to the applications needs&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#3foot|[3]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In a dynamic distributed management system, each processor keeps track of ownership of all pages within their local table.  Instead of the owner field in the Centralized Management scheme, instead there is a probOwner field which has the probable owner of the page for a page fault&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#3foot|[3]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;1foot&amp;quot;&amp;gt;[[#1body|1.]]&amp;lt;/span&amp;gt; http://en.wikipedia.org/wiki/Memory_coherence  &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;2foot&amp;quot;&amp;gt;[[#2body|2.]]&amp;lt;/span&amp;gt; http://en.wikipedia.org/wiki/Peterson%27s_algorithm  &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;3foot&amp;quot;&amp;gt;[[#3body|3.]]&amp;lt;/span&amp;gt; Li, K. and Hudak, P. Memory Coherence in Shared Virtual Memory Systems. ACM Transactions on Computer Systems, 7(4):321{359, November 1989.  &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;4foot&amp;quot;&amp;gt;[[#4body|4.]]&amp;lt;/span&amp;gt;http://web.sfc.keio.ac.jp/~rdv/keio/sfc/teaching/architecture/architecture-2007/lec08.html&lt;/div&gt;</summary>
		<author><name>Pmpatel</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_506_Spring_2011/ch7_jp&amp;diff=44579</id>
		<title>CSC/ECE 506 Spring 2011/ch7 jp</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_506_Spring_2011/ch7_jp&amp;diff=44579"/>
		<updated>2011-03-22T02:18:58Z</updated>

		<summary type="html">&lt;p&gt;Pmpatel: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Introduction=&lt;br /&gt;
&lt;br /&gt;
&amp;lt;copy introduction to shared memory architecture form previous chapters &amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Advantages of shared memory system==&lt;br /&gt;
&lt;br /&gt;
* Shared memory parallel programs and multi-threaded programs will automatically run on shared memory system.&lt;br /&gt;
* Single OS runs on shared memory system which simplifies maintenance, memory management and scheduler tasks.&lt;br /&gt;
* Amount of total memory is large as it is simply sum of all memory of individual nodes.&lt;br /&gt;
* Communicating data between caches is faster than that in message passing model.&lt;br /&gt;
* Ability of finer granularity sharing compared to message passing which adds overhead of creating/sending messages for each bit of information.&lt;br /&gt;
* Common data types can be shared between different threads running on different processors. (eg. shared data which is Read Only)&lt;br /&gt;
&lt;br /&gt;
==Disadvantages of shared memory system==&lt;br /&gt;
&lt;br /&gt;
* Cost of providing shared memory grows super linearly with number of processors compared to message passing model which grows linearly.&lt;br /&gt;
&lt;br /&gt;
==Hardware Support ==&lt;br /&gt;
Shared memory architecture needs some hardware support for the implementation unlike a message passing model which can rely on software for send and receive messages.  Three things necessary with respect to hardware support for correct execution of a shared memory parallel program on a multiprocessor system are: &lt;br /&gt;
# Cache Coherence protocol&lt;br /&gt;
# Memory consistency model&lt;br /&gt;
# Hardware Synchronization &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Cache Coherence Problem=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:sharedmem.jpg|thumbnail|700px]]	&lt;br /&gt;
http://web.sfc.keio.ac.jp/~rdv/keio/sfc/teaching/architecture/architecture-2007/lec08.html&lt;br /&gt;
&lt;br /&gt;
In a system with single processor (single core), maintaining cache coherency is simple and easy but in a multiprocessor system, it is not as simple.  Data can be present in any processors cache and protocol needs to ensure that the data is same in all caches.  If it cannot ensure that all the caches are same, then it needs to flag a cache line indicating that it is not updated.  &lt;br /&gt;
&lt;br /&gt;
In the figure shown here, this is a 4 processor shared memory system where each processor has its own cache.  Supposed processor P1 reads memory location M1 and stores it in its local cache.  Then, if P2 reads same location memory location then M1 gets stored in P2’s cache.  Now, if P1 changes value of M1, two copies of same data, residing in different caches will become different.  When P2 operates on M1, it uses the stale value of M1 that was stored in its cache.  It is responsibility of Cache Coherence Protocol to prevent this.  Hardware support is needed to provide a coherent view of data in multiple caches.  This is known as write propagation requirement.&lt;br /&gt;
&lt;br /&gt;
One may think that cache write policy can provide cache coherence but it is not true.  Cache write policy only controls how a change in value of cache is propagated to lower level cache or main memory.  It is not responsible for propagating changes to other caches. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Memory Consistency Problem=&lt;br /&gt;
&lt;br /&gt;
Memory consistency deals with the ordering of memory operations (load and store) to different memory locations.  In a single processor system, code will execute correctly if the compiler preservers the order of the access to synchronization variables and other dependent variables.  But in shared memory model with multiple processors, two threads could be access a shared data (something like a synchronization variable) and the output of the threads could change based on which thread can get to the shared data earlier.  If this happens, then the program output on uni-processor system and multi-processor program will be different.&lt;br /&gt;
&lt;br /&gt;
Maintaining program order is very important for memory consistency but it comes with performance degradation.  Various memory consistency models trades off performance to make programming easy.   &lt;br /&gt;
&lt;br /&gt;
=Hardware Synchronization=&lt;br /&gt;
&lt;br /&gt;
=Peterson's Algorithm=&lt;br /&gt;
Peterson’s algorithm, also known as Peterson’s solution, is an algorithm that addresses the critical section problem by meeting the 3 criteria of the problem: mutual exclusion, progress, and bounded waiting&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;1body&amp;quot;&amp;gt;[[#1foot|[1]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 int turn;  // turn for execution&lt;br /&gt;
 int interested[2];   // the processors interested&lt;br /&gt;
 void enter_region(int process) &lt;br /&gt;
 { &lt;br /&gt;
   int otherProcess; &lt;br /&gt;
   otherProcess = 1 - process;    &lt;br /&gt;
   interested[process]=1;  &lt;br /&gt;
   turn = process;         &lt;br /&gt;
   while(turn == process &amp;amp;&amp;amp; interested[otherProcess] == 1)&lt;br /&gt;
      {&lt;br /&gt;
  	// busy wait&lt;br /&gt;
      }&lt;br /&gt;
 } &lt;br /&gt;
 void leave_region(int process) &lt;br /&gt;
 { &lt;br /&gt;
   interested[process] = 0; &lt;br /&gt;
 }&lt;br /&gt;
The algorithm uses two variables as seen above, interested and turn.  If a flag value for interested is set to 1, it indicates the process wants to enter the critical section.  The variable turn is a placeholder for the process whose turn will be next allowed to enter the critical section.  As seen above, Process1 has been given priority over P0.&lt;br /&gt;
&lt;br /&gt;
To ensure mutual exclusion, the variable interested and turn are set to ensure only 1 can enter the critical section at a time.  To ensure Progress, once a processor has left the critical section the other processors can determine which processor is allowed into the critical section next.  To ensure bounded waiting, as seen with the above code, a process will wait no longer than 1 turn to enter the critical section as the variable turn=1 will be enabled.&lt;br /&gt;
&lt;br /&gt;
=Page tables=&lt;br /&gt;
An issue with multiprocessor systems is how to enter the critical section.  One software solution is to use Page tables to ensure mutual exclusion, progress, and bounded waiting which are the 3 criteria needed to be met&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;2body&amp;quot;&amp;gt;[[#2foot|[2]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Memory Coherence==&lt;br /&gt;
As with other forms of synchronization, page tables for multiprocessor systems must have strategies for handling data.  As discussed in Li and Hudaks article, there are two basic approaches for page synchronization, invalidation and write-broadcast.  In an invalidation approach, there is only 1 owner for each page, having either read or write access to the page.  In a write-broadcast, as the name implies, it broadcasts or writes all copies for the page data and returns the faulty instruction&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#3foot|[3]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
As mentioned in the invalidation approach, there must be an owner for the page.  There are two basic ownership approaches for page tables, fixed or dynamic.  In a fixed ownership approach, 1 processor always owns the same page.  Other processors who want read or write access to the page location must negotiate for the access.  For dynamic ownership, there are two subcategories, centralized or distributed management&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#3foot|[3]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Centralized Management==&lt;br /&gt;
In centralized management for dynamic pages, there is a single, central processor that maintains a page table which has a table for each page and each page has 3 fields: owner, copy set, and lock.  The owner field consists of the single processor which owns the page, which could also be thought as the most recent processor to have write access.  The copy set field has a list of all processors that have a copy of the page.  This field helps to avoid a broadcast.  The lock field is used for synchronizing requests&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#3foot|[3]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
==Distributed Management==&lt;br /&gt;
There are 2 schemes for Distributed Management: fixed and dynamic.  For a fixed distributed management, each processor in the system is given a predetermined subset of pages to manage.  A simple, straightforward distribution of responsibility is the divide pages evenly among the system, although there are other solutions which could be tailored to the applications needs&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#3foot|[3]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In a dynamic distributed management system, each processor keeps track of ownership of all pages within their local table.  Instead of the owner field in the Centralized Management scheme, instead there is a probOwner field which has the probable owner of the page for a page fault&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#3foot|[3]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;1foot&amp;quot;&amp;gt;[[#1body|1.]]&amp;lt;/span&amp;gt; http://en.wikipedia.org/wiki/Memory_coherence  &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;2foot&amp;quot;&amp;gt;[[#2body|2.]]&amp;lt;/span&amp;gt; http://en.wikipedia.org/wiki/Peterson%27s_algorithm  &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;3foot&amp;quot;&amp;gt;[[#3body|3.]]&amp;lt;/span&amp;gt; Li, K. and Hudak, P. Memory Coherence in Shared Virtual Memory Systems. ACM Transactions on Computer Systems, 7(4):321{359, November 1989.  &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;4foot&amp;quot;&amp;gt;[[#4body|4.]]&amp;lt;/span&amp;gt;http://web.sfc.keio.ac.jp/~rdv/keio/sfc/teaching/architecture/architecture-2007/lec08.html&lt;/div&gt;</summary>
		<author><name>Pmpatel</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_506_Spring_2011/ch7_jp&amp;diff=44564</id>
		<title>CSC/ECE 506 Spring 2011/ch7 jp</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_506_Spring_2011/ch7_jp&amp;diff=44564"/>
		<updated>2011-03-20T23:30:15Z</updated>

		<summary type="html">&lt;p&gt;Pmpatel: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Introduction=&lt;br /&gt;
&lt;br /&gt;
&amp;lt;copy introduction to shared memory architecture form previous chapters &amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Advantages of shared memory system==&lt;br /&gt;
&lt;br /&gt;
* Shared memory parallel programs and multi-threaded programs will automatically run on shared memory system.&lt;br /&gt;
* Single OS runs on shared memory system which simplifies maintenance, memory management and scheduler tasks.&lt;br /&gt;
* Amount of total memory is large as it is simply sum of all memory of individual nodes.&lt;br /&gt;
* Communicating data between caches is faster than that in message passing model.&lt;br /&gt;
* Ability of finer granularity sharing compared to message passing which adds overhead of creating/sending messages for each bit of information.&lt;br /&gt;
* Common data types can be shared between different threads running on different processors. (eg. shared data which is Read Only)&lt;br /&gt;
&lt;br /&gt;
==Disadvantages of shared memory system==&lt;br /&gt;
&lt;br /&gt;
* Cost of providing shared memory grows super linearly with number of processors compared to message passing model which grows linearly.&lt;br /&gt;
&lt;br /&gt;
==Hardware Support ==&lt;br /&gt;
Shared memory architecture needs some hardware support for the implementation unlike a message passing model which can rely on software for send and receive messages.  Three things necessary with respect to hardware support for correct execution of a shared memory parallel program on a multiprocessor system are: &lt;br /&gt;
# Cache Coherence protocol&lt;br /&gt;
# Memory consistency model&lt;br /&gt;
# Hardware Synchronization &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Cache Coherence Problem=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:sharedmem.jpg]]	&lt;br /&gt;
http://web.sfc.keio.ac.jp/~rdv/keio/sfc/teaching/architecture/architecture-2007/lec08.html&lt;br /&gt;
&lt;br /&gt;
In a system with single processor (single core), maintaining cache coherency is simple and easy but in a multiprocessor system, it is not as simple.  Data can be present in any processors cache and protocol needs to ensure that the data is same in all caches.  If it cannot ensure that all the caches are same, then it needs to flag a cache line indicating that it is not updated.  &lt;br /&gt;
&lt;br /&gt;
In the figure shown here, this is a 4 processor shared memory system where each processor has its own cache.  Supposed processor P1 reads memory location M1 and stores it in its local cache.  Then, if P2 reads same location memory location then M1 gets stored in P2’s cache.  Now, if P1 changes value of M1, two copies of same data, residing in different caches will become different.  When P2 operates on M1, it uses the stale value of M1 that was stored in its cache.  It is responsibility of Cache Coherence Protocol to prevent this.  Hardware support is needed to provide a coherent view of data in multiple caches.  This is known as write propagation requirement.&lt;br /&gt;
&lt;br /&gt;
One may think that cache write policy can provide cache coherence but it is not true.  Cache write policy only controls how a change in value of cache is propagated to lower level cache or main memory.  It is not responsible for propagating changes to other caches. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Memory Consistency Problem=&lt;br /&gt;
&lt;br /&gt;
Memory consistency deals with the ordering of memory operations (load and store) to different memory locations.  In a single processor system, code will execute correctly if the compiler preservers the order of the access to synchronization variables and other dependent variables.  But in shared memory model with multiple processors, two threads could be access a shared data (something like a synchronization variable) and the output of the threads could change based on which thread can get to the shared data earlier.  If this happens, then the program output on uni-processor system and multi-processor program will be different.&lt;br /&gt;
&lt;br /&gt;
Maintaining program order is very important for memory consistency but it comes with performance degradation.  Various memory consistency models trades off performance to make programming easy.   &lt;br /&gt;
&lt;br /&gt;
=Hardware Synchronization=&lt;br /&gt;
&lt;br /&gt;
=Peterson's Algorithm=&lt;br /&gt;
Peterson’s algorithm, also known as Peterson’s solution, is an algorithm that addresses the critical section problem by meeting the 3 criteria of the problem: mutual exclusion, progress, and bounded waiting&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;1body&amp;quot;&amp;gt;[[#1foot|[1]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 int turn;  // turn for execution&lt;br /&gt;
 int interested[2];   // the processors interested&lt;br /&gt;
 void enter_region(int process) &lt;br /&gt;
 { &lt;br /&gt;
   int otherProcess; &lt;br /&gt;
   otherProcess = 1 - process;    &lt;br /&gt;
   interested[process]=1;  &lt;br /&gt;
   turn = process;         &lt;br /&gt;
   while(turn == process &amp;amp;&amp;amp; interested[otherProcess] == 1)&lt;br /&gt;
      {&lt;br /&gt;
  	// busy wait&lt;br /&gt;
      }&lt;br /&gt;
 } &lt;br /&gt;
 void leave_region(int process) &lt;br /&gt;
 { &lt;br /&gt;
   interested[process] = 0; &lt;br /&gt;
 }&lt;br /&gt;
The algorithm uses two variables as seen above, interested and turn.  If a flag value for interested is set to 1, it indicates the process wants to enter the critical section.  The variable turn is a placeholder for the process whose turn will be next allowed to enter the critical section.  As seen above, Process1 has been given priority over P0.&lt;br /&gt;
&lt;br /&gt;
To ensure mutual exclusion, the variable interested and turn are set to ensure only 1 can enter the critical section at a time.  To ensure Progress, once a processor has left the critical section the other processors can determine which processor is allowed into the critical section next.  To ensure bounded waiting, as seen with the above code, a process will wait no longer than 1 turn to enter the critical section as the variable turn=1 will be enabled.&lt;br /&gt;
&lt;br /&gt;
=Page tables=&lt;br /&gt;
An issue with multiprocessor systems is how to enter the critical section.  One software solution is to use Page tables to ensure mutual exclusion, progress, and bounded waiting which are the 3 criteria needed to be met&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;2body&amp;quot;&amp;gt;[[#2foot|[2]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Memory Coherence==&lt;br /&gt;
As with other forms of synchronization, page tables for multiprocessor systems must have strategies for handling data.  As discussed in Li and Hudaks article, there are two basic approaches for page synchronization, invalidation and write-broadcast.  In an invalidation approach, there is only 1 owner for each page, having either read or write access to the page.  In a write-broadcast, as the name implies, it broadcasts or writes all copies for the page data and returns the faulty instruction&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#3foot|[3]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
As mentioned in the invalidation approach, there must be an owner for the page.  There are two basic ownership approaches for page tables, fixed or dynamic.  In a fixed ownership approach, 1 processor always owns the same page.  Other processors who want read or write access to the page location must negotiate for the access.  For dynamic ownership, there are two subcategories, centralized or distributed management&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#3foot|[3]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Centralized Management==&lt;br /&gt;
In centralized management for dynamic pages, there is a single, central processor that maintains a page table which has a table for each page and each page has 3 fields: owner, copy set, and lock.  The owner field consists of the single processor which owns the page, which could also be thought as the most recent processor to have write access.  The copy set field has a list of all processors that have a copy of the page.  This field helps to avoid a broadcast.  The lock field is used for synchronizing requests&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#3foot|[3]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
==Distributed Management==&lt;br /&gt;
There are 2 schemes for Distributed Management: fixed and dynamic.  For a fixed distributed management, each processor in the system is given a predetermined subset of pages to manage.  A simple, straightforward distribution of responsibility is the divide pages evenly among the system, although there are other solutions which could be tailored to the applications needs&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#3foot|[3]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In a dynamic distributed management system, each processor keeps track of ownership of all pages within their local table.  Instead of the owner field in the Centralized Management scheme, instead there is a probOwner field which has the probable owner of the page for a page fault&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#3foot|[3]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;1foot&amp;quot;&amp;gt;[[#1body|1.]]&amp;lt;/span&amp;gt; http://en.wikipedia.org/wiki/Memory_coherence  &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;2foot&amp;quot;&amp;gt;[[#2body|2.]]&amp;lt;/span&amp;gt; http://en.wikipedia.org/wiki/Peterson%27s_algorithm  &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;3foot&amp;quot;&amp;gt;[[#3body|3.]]&amp;lt;/span&amp;gt; Li, K. and Hudak, P. Memory Coherence in Shared Virtual Memory Systems. ACM Transactions on Computer Systems, 7(4):321{359, November 1989.  &amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Pmpatel</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_506_Spring_2011/ch7_jp&amp;diff=44563</id>
		<title>CSC/ECE 506 Spring 2011/ch7 jp</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_506_Spring_2011/ch7_jp&amp;diff=44563"/>
		<updated>2011-03-20T23:27:00Z</updated>

		<summary type="html">&lt;p&gt;Pmpatel: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Introduction:=&lt;br /&gt;
&lt;br /&gt;
&amp;lt;copy introduction to shared memory architecture form previous chapters &amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Advantages of shared memory system:==&lt;br /&gt;
&lt;br /&gt;
* Shared memory parallel programs and multi-threaded programs will automatically run on shared memory system.&lt;br /&gt;
* Single OS runs on shared memory system which simplifies maintenance, memory management and scheduler tasks.&lt;br /&gt;
* Amount of total memory is large as it is simply sum of all memory of individual nodes.&lt;br /&gt;
* Communicating data between caches is faster than that in message passing model.&lt;br /&gt;
* Ability of finer granularity sharing compared to message passing which adds overhead of creating/sending messages for each bit of information.&lt;br /&gt;
* Common data types can be shared between different threads running on different processors. (eg. shared data which is Read Only)&lt;br /&gt;
&lt;br /&gt;
==Disadvantages of shared memory system:==&lt;br /&gt;
&lt;br /&gt;
* Cost of providing shared memory grows super linearly with number of processors compared to message passing model which grows linearly.&lt;br /&gt;
&lt;br /&gt;
==Hardware Support ==&lt;br /&gt;
Shared memory architecture needs some hardware support for the implementation unlike a message passing model which can rely on software for send and receive messages.  Three things necessary with respect to hardware support for correct execution of a shared memory parallel program on a multiprocessor system are: &lt;br /&gt;
# Cache Coherence protocol&lt;br /&gt;
# Memory consistency model&lt;br /&gt;
# Hardware Synchronization &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Cache Coherence Problem=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:sharedmem.jpg]]	&lt;br /&gt;
http://web.sfc.keio.ac.jp/~rdv/keio/sfc/teaching/architecture/architecture-2007/lec08.html&lt;br /&gt;
&lt;br /&gt;
In a system with single processor (single core), maintaining cache coherency is simple and easy but in a multiprocessor system, it is not as simple.  Data can be present in any processors cache and protocol needs to ensure that the data is same in all caches.  If it cannot ensure that all the caches are same, then it needs to flag a cache line indicating that it is not updated.  &lt;br /&gt;
&lt;br /&gt;
In the figure shown here, this is a 4 processor shared memory system where each processor has its own cache.  Supposed processor P1 reads memory location M1 and stores it in its local cache.  Then, if P2 reads same location memory location then M1 gets stored in P2’s cache.  Now, if P1 changes value of M1, two copies of same data, residing in different caches will become different.  When P2 operates on M1, it uses the stale value of M1 that was stored in its cache.  It is responsibility of Cache Coherence Protocol to prevent this.  Hardware support is needed to provide a coherent view of data in multiple caches.  This is known as write propagation requirement.&lt;br /&gt;
&lt;br /&gt;
One may think that cache write policy can provide cache coherence but it is not true.  Cache write policy only controls how a change in value of cache is propagated to lower level cache or main memory.  It is not responsible for propagating changes to other caches. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Memory Consistency Problem=&lt;br /&gt;
&lt;br /&gt;
Memory consistency deals with the ordering of memory operations (load and store) to different memory locations.  In a single processor system, code will execute correctly if the compiler preservers the order of the access to synchronization variables and other dependent variables.  But in shared memory model with multiple processors, two threads could be access a shared data (something like a synchronization variable) and the output of the threads could change based on which thread can get to the shared data earlier.  If this happens, then the program output on uni-processor system and multi-processor program will be different.&lt;br /&gt;
&lt;br /&gt;
Maintaining program order is very important for memory consistency but it comes with performance degradation.  Various memory consistency models trades off performance to make programming easy.   &lt;br /&gt;
&lt;br /&gt;
=Hardware Synchronization=&lt;br /&gt;
&lt;br /&gt;
=Peterson's Algorithm=&lt;br /&gt;
Peterson’s algorithm, also known as Peterson’s solution, is an algorithm that addresses the critical section problem by meeting the 3 criteria of the problem: mutual exclusion, progress, and bounded waiting&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;1body&amp;quot;&amp;gt;[[#1foot|[1]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 int turn;  // turn for execution&lt;br /&gt;
 int interested[2];   // the processors interested&lt;br /&gt;
 void enter_region(int process) &lt;br /&gt;
 { &lt;br /&gt;
   int otherProcess; &lt;br /&gt;
   otherProcess = 1 - process;    &lt;br /&gt;
   interested[process]=1;  &lt;br /&gt;
   turn = process;         &lt;br /&gt;
   while(turn == process &amp;amp;&amp;amp; interested[otherProcess] == 1)&lt;br /&gt;
      {&lt;br /&gt;
  	// busy wait&lt;br /&gt;
      }&lt;br /&gt;
 } &lt;br /&gt;
 void leave_region(int process) &lt;br /&gt;
 { &lt;br /&gt;
   interested[process] = 0; &lt;br /&gt;
 }&lt;br /&gt;
The algorithm uses two variables as seen above, interested and turn.  If a flag value for interested is set to 1, it indicates the process wants to enter the critical section.  The variable turn is a placeholder for the process whose turn will be next allowed to enter the critical section.  As seen above, Process1 has been given priority over P0.&lt;br /&gt;
&lt;br /&gt;
To ensure mutual exclusion, the variable interested and turn are set to ensure only 1 can enter the critical section at a time.  To ensure Progress, once a processor has left the critical section the other processors can determine which processor is allowed into the critical section next.  To ensure bounded waiting, as seen with the above code, a process will wait no longer than 1 turn to enter the critical section as the variable turn=1 will be enabled.&lt;br /&gt;
&lt;br /&gt;
=Page tables=&lt;br /&gt;
An issue with multiprocessor systems is how to enter the critical section.  One software solution is to use Page tables to ensure mutual exclusion, progress, and bounded waiting which are the 3 criteria needed to be met&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;2body&amp;quot;&amp;gt;[[#2foot|[2]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Memory Coherence==&lt;br /&gt;
As with other forms of synchronization, page tables for multiprocessor systems must have strategies for handling data.  As discussed in Li and Hudaks article, there are two basic approaches for page synchronization, invalidation and write-broadcast.  In an invalidation approach, there is only 1 owner for each page, having either read or write access to the page.  In a write-broadcast, as the name implies, it broadcasts or writes all copies for the page data and returns the faulty instruction&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#3foot|[3]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
As mentioned in the invalidation approach, there must be an owner for the page.  There are two basic ownership approaches for page tables, fixed or dynamic.  In a fixed ownership approach, 1 processor always owns the same page.  Other processors who want read or write access to the page location must negotiate for the access.  For dynamic ownership, there are two subcategories, centralized or distributed management&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#3foot|[3]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Centralized Management==&lt;br /&gt;
In centralized management for dynamic pages, there is a single, central processor that maintains a page table which has a table for each page and each page has 3 fields: owner, copy set, and lock.  The owner field consists of the single processor which owns the page, which could also be thought as the most recent processor to have write access.  The copy set field has a list of all processors that have a copy of the page.  This field helps to avoid a broadcast.  The lock field is used for synchronizing requests&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#3foot|[3]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
==Distributed Management==&lt;br /&gt;
There are 2 schemes for Distributed Management: fixed and dynamic.  For a fixed distributed management, each processor in the system is given a predetermined subset of pages to manage.  A simple, straightforward distribution of responsibility is the divide pages evenly among the system, although there are other solutions which could be tailored to the applications needs&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#3foot|[3]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In a dynamic distributed management system, each processor keeps track of ownership of all pages within their local table.  Instead of the owner field in the Centralized Management scheme, instead there is a probOwner field which has the probable owner of the page for a page fault&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#3foot|[3]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;1foot&amp;quot;&amp;gt;[[#1body|1.]]&amp;lt;/span&amp;gt; http://en.wikipedia.org/wiki/Memory_coherence  &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;2foot&amp;quot;&amp;gt;[[#2body|2.]]&amp;lt;/span&amp;gt; http://en.wikipedia.org/wiki/Peterson%27s_algorithm  &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;3foot&amp;quot;&amp;gt;[[#3body|3.]]&amp;lt;/span&amp;gt; Li, K. and Hudak, P. Memory Coherence in Shared Virtual Memory Systems. ACM Transactions on Computer Systems, 7(4):321{359, November 1989.  &amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Pmpatel</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Sharedmem.jpg&amp;diff=44562</id>
		<title>File:Sharedmem.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Sharedmem.jpg&amp;diff=44562"/>
		<updated>2011-03-20T23:26:24Z</updated>

		<summary type="html">&lt;p&gt;Pmpatel: Shared Memory&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Shared Memory&lt;/div&gt;</summary>
		<author><name>Pmpatel</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_506_Spring_2011/ch7_jp&amp;diff=44561</id>
		<title>CSC/ECE 506 Spring 2011/ch7 jp</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_506_Spring_2011/ch7_jp&amp;diff=44561"/>
		<updated>2011-03-20T23:21:14Z</updated>

		<summary type="html">&lt;p&gt;Pmpatel: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Introduction:=&lt;br /&gt;
&lt;br /&gt;
&amp;lt;copy introduction to shared memory architecture form previous chapters &amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Advantages of shared memory system:==&lt;br /&gt;
&lt;br /&gt;
* Shared memory parallel programs and multi-threaded programs will automatically run on shared memory system.&lt;br /&gt;
* Single OS runs on shared memory system which simplifies maintenance, memory management and scheduler tasks.&lt;br /&gt;
* Amount of total memory is large as it is simply sum of all memory of individual nodes.&lt;br /&gt;
* Communicating data between caches is faster than that in message passing model.&lt;br /&gt;
* Ability of finer granularity sharing compared to message passing which adds overhead of creating/sending messages for each bit of information.&lt;br /&gt;
* Common data types can be shared between different threads running on different processors. (eg. shared data which is Read Only)&lt;br /&gt;
&lt;br /&gt;
==Disadvantages of shared memory system:==&lt;br /&gt;
&lt;br /&gt;
* Cost of providing shared memory grows super linearly with number of processors compared to message passing model which grows linearly.&lt;br /&gt;
&lt;br /&gt;
==Hardware Support ==&lt;br /&gt;
Shared memory architecture needs some hardware support for the implementation unlike a message passing model which can rely on software for send and receive messages.  Three things necessary with respect to hardware support for correct execution of a shared memory parallel program on a multiprocessor system are: &lt;br /&gt;
# Cache Coherence protocol&lt;br /&gt;
# Memory consistency model&lt;br /&gt;
# Hardware Synchronization &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Cache Coherence Problem=&lt;br /&gt;
&lt;br /&gt;
	Insert image 1,  source   http://web.sfc.keio.ac.jp/~rdv/keio/sfc/teaching/architecture/architecture-2007/lec08.html&lt;br /&gt;
&lt;br /&gt;
In a system with single processor (single core), maintaining cache coherency is simple and easy but in a multiprocessor system, it is not as simple.  Data can be present in any processors cache and protocol needs to ensure that the data is same in all caches.  If it cannot ensure that all the caches are same, then it needs to flag a cache line indicating that it is not updated.  &lt;br /&gt;
&lt;br /&gt;
In the figure shown here, this is a 4 processor shared memory system where each processor has its own cache.  Supposed processor P1 reads memory location M1 and stores it in its local cache.  Then, if P2 reads same location memory location then M1 gets stored in P2’s cache.  Now, if P1 changes value of M1, two copies of same data, residing in different caches will become different.  When P2 operates on M1, it uses the stale value of M1 that was stored in its cache.  It is responsibility of Cache Coherence Protocol to prevent this.  Hardware support is needed to provide a coherent view of data in multiple caches.  This is known as write propagation requirement.&lt;br /&gt;
&lt;br /&gt;
One may think that cache write policy can provide cache coherence but it is not true.  Cache write policy only controls how a change in value of cache is propagated to lower level cache or main memory.  It is not responsible for propagating changes to other caches. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Memory Consistency Problem=&lt;br /&gt;
&lt;br /&gt;
Memory consistency deals with the ordering of memory operations (load and store) to different memory locations.  In a single processor system, code will execute correctly if the compiler preservers the order of the access to synchronization variables and other dependent variables.  But in shared memory model with multiple processors, two threads could be access a shared data (something like a synchronization variable) and the output of the threads could change based on which thread can get to the shared data earlier.  If this happens, then the program output on uni-processor system and multi-processor program will be different.&lt;br /&gt;
&lt;br /&gt;
Maintaining program order is very important for memory consistency but it comes with performance degradation.  Various memory consistency models trades off performance to make programming easy.   &lt;br /&gt;
&lt;br /&gt;
=Hardware Synchronization=&lt;br /&gt;
&lt;br /&gt;
=Peterson's Algorithm=&lt;br /&gt;
Peterson’s algorithm, also known as Peterson’s solution, is an algorithm that addresses the critical section problem by meeting the 3 criteria of the problem: mutual exclusion, progress, and bounded waiting&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;1body&amp;quot;&amp;gt;[[#1foot|[1]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 int turn;  // turn for execution&lt;br /&gt;
 int interested[2];   // the processors interested&lt;br /&gt;
 void enter_region(int process) &lt;br /&gt;
 { &lt;br /&gt;
   int otherProcess; &lt;br /&gt;
   otherProcess = 1 - process;    &lt;br /&gt;
   interested[process]=1;  &lt;br /&gt;
   turn = process;         &lt;br /&gt;
   while(turn == process &amp;amp;&amp;amp; interested[otherProcess] == 1)&lt;br /&gt;
      {&lt;br /&gt;
  	// busy wait&lt;br /&gt;
      }&lt;br /&gt;
 } &lt;br /&gt;
 void leave_region(int process) &lt;br /&gt;
 { &lt;br /&gt;
   interested[process] = 0; &lt;br /&gt;
 }&lt;br /&gt;
The algorithm uses two variables as seen above, interested and turn.  If a flag value for interested is set to 1, it indicates the process wants to enter the critical section.  The variable turn is a placeholder for the process whose turn will be next allowed to enter the critical section.  As seen above, Process1 has been given priority over P0.&lt;br /&gt;
&lt;br /&gt;
To ensure mutual exclusion, the variable interested and turn are set to ensure only 1 can enter the critical section at a time.  To ensure Progress, once a processor has left the critical section the other processors can determine which processor is allowed into the critical section next.  To ensure bounded waiting, as seen with the above code, a process will wait no longer than 1 turn to enter the critical section as the variable turn=1 will be enabled.&lt;br /&gt;
&lt;br /&gt;
=Page tables=&lt;br /&gt;
An issue with multiprocessor systems is how to enter the critical section.  One software solution is to use Page tables to ensure mutual exclusion, progress, and bounded waiting which are the 3 criteria needed to be met&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;2body&amp;quot;&amp;gt;[[#2foot|[2]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Memory Coherence==&lt;br /&gt;
As with other forms of synchronization, page tables for multiprocessor systems must have strategies for handling data.  As discussed in Li and Hudaks article, there are two basic approaches for page synchronization, invalidation and write-broadcast.  In an invalidation approach, there is only 1 owner for each page, having either read or write access to the page.  In a write-broadcast, as the name implies, it broadcasts or writes all copies for the page data and returns the faulty instruction&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#3foot|[3]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
As mentioned in the invalidation approach, there must be an owner for the page.  There are two basic ownership approaches for page tables, fixed or dynamic.  In a fixed ownership approach, 1 processor always owns the same page.  Other processors who want read or write access to the page location must negotiate for the access.  For dynamic ownership, there are two subcategories, centralized or distributed management&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#3foot|[3]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Centralized Management==&lt;br /&gt;
In centralized management for dynamic pages, there is a single, central processor that maintains a page table which has a table for each page and each page has 3 fields: owner, copy set, and lock.  The owner field consists of the single processor which owns the page, which could also be thought as the most recent processor to have write access.  The copy set field has a list of all processors that have a copy of the page.  This field helps to avoid a broadcast.  The lock field is used for synchronizing requests&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#3foot|[3]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
==Distributed Management==&lt;br /&gt;
There are 2 schemes for Distributed Management: fixed and dynamic.  For a fixed distributed management, each processor in the system is given a predetermined subset of pages to manage.  A simple, straightforward distribution of responsibility is the divide pages evenly among the system, although there are other solutions which could be tailored to the applications needs&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#3foot|[3]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In a dynamic distributed management system, each processor keeps track of ownership of all pages within their local table.  Instead of the owner field in the Centralized Management scheme, instead there is a probOwner field which has the probable owner of the page for a page fault&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#3foot|[3]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;1foot&amp;quot;&amp;gt;[[#1body|1.]]&amp;lt;/span&amp;gt; http://en.wikipedia.org/wiki/Memory_coherence  &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;2foot&amp;quot;&amp;gt;[[#2body|2.]]&amp;lt;/span&amp;gt; http://en.wikipedia.org/wiki/Peterson%27s_algorithm  &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;3foot&amp;quot;&amp;gt;[[#3body|3.]]&amp;lt;/span&amp;gt; Li, K. and Hudak, P. Memory Coherence in Shared Virtual Memory Systems. ACM Transactions on Computer Systems, 7(4):321{359, November 1989.  &amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Pmpatel</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_506_Spring_2011/ch7_jp&amp;diff=44560</id>
		<title>CSC/ECE 506 Spring 2011/ch7 jp</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_506_Spring_2011/ch7_jp&amp;diff=44560"/>
		<updated>2011-03-20T23:20:07Z</updated>

		<summary type="html">&lt;p&gt;Pmpatel: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Introduction:=&lt;br /&gt;
&lt;br /&gt;
&amp;lt;copy introduction to shared memory architecture form previous chapters &amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Advantages of shared memory system:==&lt;br /&gt;
&lt;br /&gt;
* Shared memory parallel programs and multi-threaded programs will automatically run on shared memory system.&lt;br /&gt;
* Single OS runs on shared memory system which simplifies maintenance, memory management and scheduler tasks.&lt;br /&gt;
* Amount of total memory is large as it is simply sum of all memory of individual nodes.&lt;br /&gt;
* Communicating data between caches is faster than that in message passing model.&lt;br /&gt;
* Ability of finer granularity sharing compared to message passing which adds overhead of creating/sending messages for each bit of information.&lt;br /&gt;
* Common data types can be shared between different threads running on different processors. (eg. shared data which is Read Only)&lt;br /&gt;
&lt;br /&gt;
==Disadvantages of shared memory system:==&lt;br /&gt;
&lt;br /&gt;
* Cost of providing shared memory grows super linearly with number of processors compared to message passing model which grows linearly.&lt;br /&gt;
&lt;br /&gt;
==Hardware Support ==&lt;br /&gt;
Shared memory architecture needs some hardware support for the implementation unlike a message passing model which can rely on software for send and receive messages.  Three things necessary with respect to hardware support for correct execution of a shared memory parallel program on a multiprocessor system are: &lt;br /&gt;
1.	Cache Coherence protocol&lt;br /&gt;
2.	Memory consistency model&lt;br /&gt;
3.	Hardware Synchronization &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Cache Coherence Problem=&lt;br /&gt;
&lt;br /&gt;
	Insert image 1,  source   http://web.sfc.keio.ac.jp/~rdv/keio/sfc/teaching/architecture/architecture-2007/lec08.html&lt;br /&gt;
&lt;br /&gt;
In a system with single processor (single core), maintaining cache coherency is simple and easy but in a multiprocessor system, it is not as simple.  Data can be present in any processors cache and protocol needs to ensure that the data is same in all caches.  If it cannot ensure that all the caches are same, then it needs to flag a cache line indicating that it is not updated.  &lt;br /&gt;
&lt;br /&gt;
In the figure shown here, this is a 4 processor shared memory system where each processor has its own cache.  Supposed processor P1 reads memory location M1 and stores it in its local cache.  Then, if P2 reads same location memory location then M1 gets stored in P2’s cache.  Now, if P1 changes value of M1, two copies of same data, residing in different caches will become different.  When P2 operates on M1, it uses the stale value of M1 that was stored in its cache.  It is responsibility of Cache Coherence Protocol to prevent this.  Hardware support is needed to provide a coherent view of data in multiple caches.  This is known as write propagation requirement.&lt;br /&gt;
&lt;br /&gt;
One may think that cache write policy can provide cache coherence but it is not true.  Cache write policy only controls how a change in value of cache is propagated to lower level cache or main memory.  It is not responsible for propagating changes to other caches. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Memory Consistency Problem=&lt;br /&gt;
&lt;br /&gt;
Memory consistency deals with the ordering of memory operations (load and store) to different memory locations.  In a single processor system, code will execute correctly if the compiler preservers the order of the access to synchronization variables and other dependent variables.  But in shared memory model with multiple processors, two threads could be access a shared data (something like a synchronization variable) and the output of the threads could change based on which thread can get to the shared data earlier.  If this happens, then the program output on uni-processor system and multi-processor program will be different.&lt;br /&gt;
&lt;br /&gt;
Maintaining program order is very important for memory consistency but it comes with performance degradation.  Various memory consistency models trades off performance to make programming easy.   &lt;br /&gt;
&lt;br /&gt;
=Hardware Synchronization=&lt;br /&gt;
&lt;br /&gt;
=Peterson's Algorithm=&lt;br /&gt;
Peterson’s algorithm, also known as Peterson’s solution, is an algorithm that addresses the critical section problem by meeting the 3 criteria of the problem: mutual exclusion, progress, and bounded waiting&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;1body&amp;quot;&amp;gt;[[#1foot|[1]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 int turn;  // turn for execution&lt;br /&gt;
 int interested[2];   // the processors interested&lt;br /&gt;
 void enter_region(int process) &lt;br /&gt;
 { &lt;br /&gt;
   int otherProcess; &lt;br /&gt;
   otherProcess = 1 - process;    &lt;br /&gt;
   interested[process]=1;  &lt;br /&gt;
   turn = process;         &lt;br /&gt;
   while(turn == process &amp;amp;&amp;amp; interested[otherProcess] == 1)&lt;br /&gt;
      {&lt;br /&gt;
  	// busy wait&lt;br /&gt;
      }&lt;br /&gt;
 } &lt;br /&gt;
 void leave_region(int process) &lt;br /&gt;
 { &lt;br /&gt;
   interested[process] = 0; &lt;br /&gt;
 }&lt;br /&gt;
The algorithm uses two variables as seen above, interested and turn.  If a flag value for interested is set to 1, it indicates the process wants to enter the critical section.  The variable turn is a placeholder for the process whose turn will be next allowed to enter the critical section.  As seen above, Process1 has been given priority over P0.&lt;br /&gt;
&lt;br /&gt;
To ensure mutual exclusion, the variable interested and turn are set to ensure only 1 can enter the critical section at a time.  To ensure Progress, once a processor has left the critical section the other processors can determine which processor is allowed into the critical section next.  To ensure bounded waiting, as seen with the above code, a process will wait no longer than 1 turn to enter the critical section as the variable turn=1 will be enabled.&lt;br /&gt;
&lt;br /&gt;
=Page tables=&lt;br /&gt;
An issue with multiprocessor systems is how to enter the critical section.  One software solution is to use Page tables to ensure mutual exclusion, progress, and bounded waiting which are the 3 criteria needed to be met&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;2body&amp;quot;&amp;gt;[[#2foot|[2]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Memory Coherence==&lt;br /&gt;
As with other forms of synchronization, page tables for multiprocessor systems must have strategies for handling data.  As discussed in Li and Hudaks article, there are two basic approaches for page synchronization, invalidation and write-broadcast.  In an invalidation approach, there is only 1 owner for each page, having either read or write access to the page.  In a write-broadcast, as the name implies, it broadcasts or writes all copies for the page data and returns the faulty instruction&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#3foot|[3]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
As mentioned in the invalidation approach, there must be an owner for the page.  There are two basic ownership approaches for page tables, fixed or dynamic.  In a fixed ownership approach, 1 processor always owns the same page.  Other processors who want read or write access to the page location must negotiate for the access.  For dynamic ownership, there are two subcategories, centralized or distributed management&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#3foot|[3]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Centralized Management==&lt;br /&gt;
In centralized management for dynamic pages, there is a single, central processor that maintains a page table which has a table for each page and each page has 3 fields: owner, copy set, and lock.  The owner field consists of the single processor which owns the page, which could also be thought as the most recent processor to have write access.  The copy set field has a list of all processors that have a copy of the page.  This field helps to avoid a broadcast.  The lock field is used for synchronizing requests&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#3foot|[3]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
==Distributed Management==&lt;br /&gt;
There are 2 schemes for Distributed Management: fixed and dynamic.  For a fixed distributed management, each processor in the system is given a predetermined subset of pages to manage.  A simple, straightforward distribution of responsibility is the divide pages evenly among the system, although there are other solutions which could be tailored to the applications needs&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#3foot|[3]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In a dynamic distributed management system, each processor keeps track of ownership of all pages within their local table.  Instead of the owner field in the Centralized Management scheme, instead there is a probOwner field which has the probable owner of the page for a page fault&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#3foot|[3]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;1foot&amp;quot;&amp;gt;[[#1body|1.]]&amp;lt;/span&amp;gt; http://en.wikipedia.org/wiki/Memory_coherence  &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;2foot&amp;quot;&amp;gt;[[#2body|2.]]&amp;lt;/span&amp;gt; http://en.wikipedia.org/wiki/Peterson%27s_algorithm  &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;3foot&amp;quot;&amp;gt;[[#3body|3.]]&amp;lt;/span&amp;gt; Li, K. and Hudak, P. Memory Coherence in Shared Virtual Memory Systems. ACM Transactions on Computer Systems, 7(4):321{359, November 1989.  &amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Pmpatel</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_506_Spring_2011/ch7_jp&amp;diff=44559</id>
		<title>CSC/ECE 506 Spring 2011/ch7 jp</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_506_Spring_2011/ch7_jp&amp;diff=44559"/>
		<updated>2011-03-20T23:19:27Z</updated>

		<summary type="html">&lt;p&gt;Pmpatel: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Introduction:=&lt;br /&gt;
&lt;br /&gt;
&amp;lt;copy introduction to shared memory architecture form previous chapters &amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Advantages of shared memory system:=&lt;br /&gt;
&lt;br /&gt;
* Shared memory parallel programs and multi-threaded programs will automatically run on shared memory system.&lt;br /&gt;
* Single OS runs on shared memory system which simplifies maintenance, memory management and scheduler tasks.&lt;br /&gt;
* Amount of total memory is large as it is simply sum of all memory of individual nodes.&lt;br /&gt;
* Communicating data between caches is faster than that in message passing model.&lt;br /&gt;
* Ability of finer granularity sharing compared to message passing which adds overhead of creating/sending messages for each bit of information.&lt;br /&gt;
* Common data types can be shared between different threads running on different processors. (eg. shared data which is Read Only)&lt;br /&gt;
&lt;br /&gt;
Disadvantages of shared memory system:&lt;br /&gt;
&lt;br /&gt;
* Cost of providing shared memory grows super linearly with number of processors compared to message passing model which grows linearly.&lt;br /&gt;
&lt;br /&gt;
==Hardware Support ==&lt;br /&gt;
Shared memory architecture needs some hardware support for the implementation unlike a message passing model which can rely on software for send and receive messages.  Three things necessary with respect to hardware support for correct execution of a shared memory parallel program on a multiprocessor system are: &lt;br /&gt;
1.	Cache Coherence protocol&lt;br /&gt;
2.	Memory consistency model&lt;br /&gt;
3.	Hardware Synchronization &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Cache Coherence Problem=&lt;br /&gt;
&lt;br /&gt;
	Insert image 1,  source   http://web.sfc.keio.ac.jp/~rdv/keio/sfc/teaching/architecture/architecture-2007/lec08.html&lt;br /&gt;
&lt;br /&gt;
In a system with single processor (single core), maintaining cache coherency is simple and easy but in a multiprocessor system, it is not as simple.  Data can be present in any processors cache and protocol needs to ensure that the data is same in all caches.  If it cannot ensure that all the caches are same, then it needs to flag a cache line indicating that it is not updated.  &lt;br /&gt;
&lt;br /&gt;
In the figure shown here, this is a 4 processor shared memory system where each processor has its own cache.  Supposed processor P1 reads memory location M1 and stores it in its local cache.  Then, if P2 reads same location memory location then M1 gets stored in P2’s cache.  Now, if P1 changes value of M1, two copies of same data, residing in different caches will become different.  When P2 operates on M1, it uses the stale value of M1 that was stored in its cache.  It is responsibility of Cache Coherence Protocol to prevent this.  Hardware support is needed to provide a coherent view of data in multiple caches.  This is known as write propagation requirement.&lt;br /&gt;
&lt;br /&gt;
One may think that cache write policy can provide cache coherence but it is not true.  Cache write policy only controls how a change in value of cache is propagated to lower level cache or main memory.  It is not responsible for propagating changes to other caches. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Memory Consistency Problem=&lt;br /&gt;
&lt;br /&gt;
Memory consistency deals with the ordering of memory operations (load and store) to different memory locations.  In a single processor system, code will execute correctly if the compiler preservers the order of the access to synchronization variables and other dependent variables.  But in shared memory model with multiple processors, two threads could be access a shared data (something like a synchronization variable) and the output of the threads could change based on which thread can get to the shared data earlier.  If this happens, then the program output on uni-processor system and multi-processor program will be different.&lt;br /&gt;
&lt;br /&gt;
Maintaining program order is very important for memory consistency but it comes with performance degradation.  Various memory consistency models trades off performance to make programming easy.   &lt;br /&gt;
&lt;br /&gt;
=Hardware Synchronization=&lt;br /&gt;
&lt;br /&gt;
=Peterson's Algorithm=&lt;br /&gt;
Peterson’s algorithm, also known as Peterson’s solution, is an algorithm that addresses the critical section problem by meeting the 3 criteria of the problem: mutual exclusion, progress, and bounded waiting&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;1body&amp;quot;&amp;gt;[[#1foot|[1]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 int turn;  // turn for execution&lt;br /&gt;
 int interested[2];   // the processors interested&lt;br /&gt;
 void enter_region(int process) &lt;br /&gt;
 { &lt;br /&gt;
   int otherProcess; &lt;br /&gt;
   otherProcess = 1 - process;    &lt;br /&gt;
   interested[process]=1;  &lt;br /&gt;
   turn = process;         &lt;br /&gt;
   while(turn == process &amp;amp;&amp;amp; interested[otherProcess] == 1)&lt;br /&gt;
      {&lt;br /&gt;
  	// busy wait&lt;br /&gt;
      }&lt;br /&gt;
 } &lt;br /&gt;
 void leave_region(int process) &lt;br /&gt;
 { &lt;br /&gt;
   interested[process] = 0; &lt;br /&gt;
 }&lt;br /&gt;
The algorithm uses two variables as seen above, interested and turn.  If a flag value for interested is set to 1, it indicates the process wants to enter the critical section.  The variable turn is a placeholder for the process whose turn will be next allowed to enter the critical section.  As seen above, Process1 has been given priority over P0.&lt;br /&gt;
&lt;br /&gt;
To ensure mutual exclusion, the variable interested and turn are set to ensure only 1 can enter the critical section at a time.  To ensure Progress, once a processor has left the critical section the other processors can determine which processor is allowed into the critical section next.  To ensure bounded waiting, as seen with the above code, a process will wait no longer than 1 turn to enter the critical section as the variable turn=1 will be enabled.&lt;br /&gt;
&lt;br /&gt;
=Page tables=&lt;br /&gt;
An issue with multiprocessor systems is how to enter the critical section.  One software solution is to use Page tables to ensure mutual exclusion, progress, and bounded waiting which are the 3 criteria needed to be met&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;2body&amp;quot;&amp;gt;[[#2foot|[2]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Memory Coherence==&lt;br /&gt;
As with other forms of synchronization, page tables for multiprocessor systems must have strategies for handling data.  As discussed in Li and Hudaks article, there are two basic approaches for page synchronization, invalidation and write-broadcast.  In an invalidation approach, there is only 1 owner for each page, having either read or write access to the page.  In a write-broadcast, as the name implies, it broadcasts or writes all copies for the page data and returns the faulty instruction&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#3foot|[3]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
As mentioned in the invalidation approach, there must be an owner for the page.  There are two basic ownership approaches for page tables, fixed or dynamic.  In a fixed ownership approach, 1 processor always owns the same page.  Other processors who want read or write access to the page location must negotiate for the access.  For dynamic ownership, there are two subcategories, centralized or distributed management&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#3foot|[3]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Centralized Management==&lt;br /&gt;
In centralized management for dynamic pages, there is a single, central processor that maintains a page table which has a table for each page and each page has 3 fields: owner, copy set, and lock.  The owner field consists of the single processor which owns the page, which could also be thought as the most recent processor to have write access.  The copy set field has a list of all processors that have a copy of the page.  This field helps to avoid a broadcast.  The lock field is used for synchronizing requests&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#3foot|[3]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
==Distributed Management==&lt;br /&gt;
There are 2 schemes for Distributed Management: fixed and dynamic.  For a fixed distributed management, each processor in the system is given a predetermined subset of pages to manage.  A simple, straightforward distribution of responsibility is the divide pages evenly among the system, although there are other solutions which could be tailored to the applications needs&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#3foot|[3]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In a dynamic distributed management system, each processor keeps track of ownership of all pages within their local table.  Instead of the owner field in the Centralized Management scheme, instead there is a probOwner field which has the probable owner of the page for a page fault&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#3foot|[3]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;1foot&amp;quot;&amp;gt;[[#1body|1.]]&amp;lt;/span&amp;gt; http://en.wikipedia.org/wiki/Memory_coherence  &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;2foot&amp;quot;&amp;gt;[[#2body|2.]]&amp;lt;/span&amp;gt; http://en.wikipedia.org/wiki/Peterson%27s_algorithm  &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;3foot&amp;quot;&amp;gt;[[#3body|3.]]&amp;lt;/span&amp;gt; Li, K. and Hudak, P. Memory Coherence in Shared Virtual Memory Systems. ACM Transactions on Computer Systems, 7(4):321{359, November 1989.  &amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Pmpatel</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_506_Spring_2011/ch7_jp&amp;diff=44558</id>
		<title>CSC/ECE 506 Spring 2011/ch7 jp</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_506_Spring_2011/ch7_jp&amp;diff=44558"/>
		<updated>2011-03-20T23:18:35Z</updated>

		<summary type="html">&lt;p&gt;Pmpatel: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Introduction:=&lt;br /&gt;
&lt;br /&gt;
&amp;lt;copy introduction to shared memory architecture form previous chapters &amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Advantages of shared memory system:=&lt;br /&gt;
&lt;br /&gt;
•Shared memory parallel programs and multi-threaded programs will automatically run on shared memory system.&lt;br /&gt;
•Single OS runs on shared memory system which simplifies maintenance, memory management and scheduler tasks.&lt;br /&gt;
•Amount of total memory is large as it is simply sum of all memory of individual nodes.&lt;br /&gt;
•Communicating data between caches is faster than that in message passing model.&lt;br /&gt;
•Ability of finer granularity sharing compared to message passing which adds overhead of creating/sending messages for each bit of information.&lt;br /&gt;
•Common data types can be shared between different threads running on different processors. (eg. shared data which is Read Only)&lt;br /&gt;
&lt;br /&gt;
Disadvantages of shared memory system:&lt;br /&gt;
&lt;br /&gt;
•Cost of providing shared memory grows super linearly with number of processors compared to message passing model which grows linearly.&lt;br /&gt;
&lt;br /&gt;
==Hardware Support ==&lt;br /&gt;
Shared memory architecture needs some hardware support for the implementation unlike a message passing model which can rely on software for send and receive messages.  Three things necessary with respect to hardware support for correct execution of a shared memory parallel program on a multiprocessor system are: &lt;br /&gt;
1.	Cache Coherence protocol&lt;br /&gt;
2.	Memory consistency model&lt;br /&gt;
3.	Hardware Synchronization &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Cache Coherence Problem=&lt;br /&gt;
&lt;br /&gt;
	Insert image 1,  source   http://web.sfc.keio.ac.jp/~rdv/keio/sfc/teaching/architecture/architecture-2007/lec08.html&lt;br /&gt;
&lt;br /&gt;
In a system with single processor (single core), maintaining cache coherency is simple and easy but in a multiprocessor system, it is not as simple.  Data can be present in any processors cache and protocol needs to ensure that the data is same in all caches.  If it cannot ensure that all the caches are same, then it needs to flag a cache line indicating that it is not updated.  &lt;br /&gt;
&lt;br /&gt;
In the figure shown here, this is a 4 processor shared memory system where each processor has its own cache.  Supposed processor P1 reads memory location M1 and stores it in its local cache.  Then, if P2 reads same location memory location then M1 gets stored in P2’s cache.  Now, if P1 changes value of M1, two copies of same data, residing in different caches will become different.  When P2 operates on M1, it uses the stale value of M1 that was stored in its cache.  It is responsibility of Cache Coherence Protocol to prevent this.  Hardware support is needed to provide a coherent view of data in multiple caches.  This is known as write propagation requirement.&lt;br /&gt;
&lt;br /&gt;
One may think that cache write policy can provide cache coherence but it is not true.  Cache write policy only controls how a change in value of cache is propagated to lower level cache or main memory.  It is not responsible for propagating changes to other caches. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Memory Consistency Problem=&lt;br /&gt;
&lt;br /&gt;
Memory consistency deals with the ordering of memory operations (load and store) to different memory locations.  In a single processor system, code will execute correctly if the compiler preservers the order of the access to synchronization variables and other dependent variables.  But in shared memory model with multiple processors, two threads could be access a shared data (something like a synchronization variable) and the output of the threads could change based on which thread can get to the shared data earlier.  If this happens, then the program output on uni-processor system and multi-processor program will be different.&lt;br /&gt;
&lt;br /&gt;
Maintaining program order is very important for memory consistency but it comes with performance degradation.  Various memory consistency models trades off performance to make programming easy.   &lt;br /&gt;
&lt;br /&gt;
=Hardware Synchronization=&lt;br /&gt;
&lt;br /&gt;
=Peterson's Algorithm=&lt;br /&gt;
Peterson’s algorithm, also known as Peterson’s solution, is an algorithm that addresses the critical section problem by meeting the 3 criteria of the problem: mutual exclusion, progress, and bounded waiting&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;1body&amp;quot;&amp;gt;[[#1foot|[1]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 int turn;  // turn for execution&lt;br /&gt;
 int interested[2];   // the processors interested&lt;br /&gt;
 void enter_region(int process) &lt;br /&gt;
 { &lt;br /&gt;
   int otherProcess; &lt;br /&gt;
   otherProcess = 1 - process;    &lt;br /&gt;
   interested[process]=1;  &lt;br /&gt;
   turn = process;         &lt;br /&gt;
   while(turn == process &amp;amp;&amp;amp; interested[otherProcess] == 1)&lt;br /&gt;
      {&lt;br /&gt;
  	// busy wait&lt;br /&gt;
      }&lt;br /&gt;
 } &lt;br /&gt;
 void leave_region(int process) &lt;br /&gt;
 { &lt;br /&gt;
   interested[process] = 0; &lt;br /&gt;
 }&lt;br /&gt;
The algorithm uses two variables as seen above, interested and turn.  If a flag value for interested is set to 1, it indicates the process wants to enter the critical section.  The variable turn is a placeholder for the process whose turn will be next allowed to enter the critical section.  As seen above, Process1 has been given priority over P0.&lt;br /&gt;
&lt;br /&gt;
To ensure mutual exclusion, the variable interested and turn are set to ensure only 1 can enter the critical section at a time.  To ensure Progress, once a processor has left the critical section the other processors can determine which processor is allowed into the critical section next.  To ensure bounded waiting, as seen with the above code, a process will wait no longer than 1 turn to enter the critical section as the variable turn=1 will be enabled.&lt;br /&gt;
&lt;br /&gt;
=Page tables=&lt;br /&gt;
An issue with multiprocessor systems is how to enter the critical section.  One software solution is to use Page tables to ensure mutual exclusion, progress, and bounded waiting which are the 3 criteria needed to be met&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;2body&amp;quot;&amp;gt;[[#2foot|[2]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Memory Coherence==&lt;br /&gt;
As with other forms of synchronization, page tables for multiprocessor systems must have strategies for handling data.  As discussed in Li and Hudaks article, there are two basic approaches for page synchronization, invalidation and write-broadcast.  In an invalidation approach, there is only 1 owner for each page, having either read or write access to the page.  In a write-broadcast, as the name implies, it broadcasts or writes all copies for the page data and returns the faulty instruction&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#3foot|[3]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
As mentioned in the invalidation approach, there must be an owner for the page.  There are two basic ownership approaches for page tables, fixed or dynamic.  In a fixed ownership approach, 1 processor always owns the same page.  Other processors who want read or write access to the page location must negotiate for the access.  For dynamic ownership, there are two subcategories, centralized or distributed management&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#3foot|[3]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Centralized Management==&lt;br /&gt;
In centralized management for dynamic pages, there is a single, central processor that maintains a page table which has a table for each page and each page has 3 fields: owner, copy set, and lock.  The owner field consists of the single processor which owns the page, which could also be thought as the most recent processor to have write access.  The copy set field has a list of all processors that have a copy of the page.  This field helps to avoid a broadcast.  The lock field is used for synchronizing requests&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#3foot|[3]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
==Distributed Management==&lt;br /&gt;
There are 2 schemes for Distributed Management: fixed and dynamic.  For a fixed distributed management, each processor in the system is given a predetermined subset of pages to manage.  A simple, straightforward distribution of responsibility is the divide pages evenly among the system, although there are other solutions which could be tailored to the applications needs&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#3foot|[3]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In a dynamic distributed management system, each processor keeps track of ownership of all pages within their local table.  Instead of the owner field in the Centralized Management scheme, instead there is a probOwner field which has the probable owner of the page for a page fault&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#3foot|[3]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;1foot&amp;quot;&amp;gt;[[#1body|1.]]&amp;lt;/span&amp;gt; http://en.wikipedia.org/wiki/Memory_coherence  &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;2foot&amp;quot;&amp;gt;[[#2body|2.]]&amp;lt;/span&amp;gt; http://en.wikipedia.org/wiki/Peterson%27s_algorithm  &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;3foot&amp;quot;&amp;gt;[[#3body|3.]]&amp;lt;/span&amp;gt; Li, K. and Hudak, P. Memory Coherence in Shared Virtual Memory Systems. ACM Transactions on Computer Systems, 7(4):321{359, November 1989.  &amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Pmpatel</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_506_Spring_2011/ch7_jp&amp;diff=44557</id>
		<title>CSC/ECE 506 Spring 2011/ch7 jp</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_506_Spring_2011/ch7_jp&amp;diff=44557"/>
		<updated>2011-03-20T23:17:30Z</updated>

		<summary type="html">&lt;p&gt;Pmpatel: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Introduction:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;copy introduction to shared memory architecture form previous chapters &amp;gt;&lt;br /&gt;
&lt;br /&gt;
Advantages of shared memory system:&lt;br /&gt;
&lt;br /&gt;
•	Shared memory parallel programs and multi-threaded programs will automatically run on shared memory system.&lt;br /&gt;
•	Single OS runs on shared memory system which simplifies maintenance, memory management and scheduler tasks.&lt;br /&gt;
•	Amount of total memory is large as it is simply sum of all memory of individual nodes.&lt;br /&gt;
•	Communicating data between caches is faster than that in message passing model.&lt;br /&gt;
•	Ability of finer granularity sharing compared to message passing which adds overhead of creating/sending messages for each bit of information.&lt;br /&gt;
•	Common data types can be shared between different threads running on different processors. (eg. shared data which is Read Only)&lt;br /&gt;
&lt;br /&gt;
Disadvantages of shared memory system:&lt;br /&gt;
&lt;br /&gt;
•	Cost of providing shared memory grows super linearly with number of processors compared to message passing model which grows linearly.&lt;br /&gt;
&lt;br /&gt;
Hardware Support &lt;br /&gt;
Shared memory architecture needs some hardware support for the implementation unlike a message passing model which can rely on software for send and receive messages.  Three things necessary with respect to hardware support for correct execution of a shared memory parallel program on a multiprocessor system are: &lt;br /&gt;
1.	Cache Coherence protocol&lt;br /&gt;
2.	Memory consistency model&lt;br /&gt;
3.	Hardware Synchronization &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Cache Coherence Problem=&lt;br /&gt;
&lt;br /&gt;
	Insert image 1,  source   http://web.sfc.keio.ac.jp/~rdv/keio/sfc/teaching/architecture/architecture-2007/lec08.html&lt;br /&gt;
&lt;br /&gt;
In a system with single processor (single core), maintaining cache coherency is simple and easy but in a multiprocessor system, it is not as simple.  Data can be present in any processors cache and protocol needs to ensure that the data is same in all caches.  If it cannot ensure that all the caches are same, then it needs to flag a cache line indicating that it is not updated.  &lt;br /&gt;
&lt;br /&gt;
In the figure shown here, this is a 4 processor shared memory system where each processor has its own cache.  Supposed processor P1 reads memory location M1 and stores it in its local cache.  Then, if P2 reads same location memory location then M1 gets stored in P2’s cache.  Now, if P1 changes value of M1, two copies of same data, residing in different caches will become different.  When P2 operates on M1, it uses the stale value of M1 that was stored in its cache.  It is responsibility of Cache Coherence Protocol to prevent this.  Hardware support is needed to provide a coherent view of data in multiple caches.  This is known as write propagation requirement.&lt;br /&gt;
&lt;br /&gt;
One may think that cache write policy can provide cache coherence but it is not true.  Cache write policy only controls how a change in value of cache is propagated to lower level cache or main memory.  It is not responsible for propagating changes to other caches. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Memory Consistency Problem=&lt;br /&gt;
&lt;br /&gt;
Memory consistency deals with the ordering of memory operations (load and store) to different memory locations.  In a single processor system, code will execute correctly if the compiler preservers the order of the access to synchronization variables and other dependent variables.  But in shared memory model with multiple processors, two threads could be access a shared data (something like a synchronization variable) and the output of the threads could change based on which thread can get to the shared data earlier.  If this happens, then the program output on uni-processor system and multi-processor program will be different.&lt;br /&gt;
&lt;br /&gt;
Maintaining program order is very important for memory consistency but it comes with performance degradation.  Various memory consistency models trades off performance to make programming easy.   &lt;br /&gt;
&lt;br /&gt;
=Hardware Synchronization=&lt;br /&gt;
&lt;br /&gt;
=Peterson's Algorithm=&lt;br /&gt;
Peterson’s algorithm, also known as Peterson’s solution, is an algorithm that addresses the critical section problem by meeting the 3 criteria of the problem: mutual exclusion, progress, and bounded waiting&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;1body&amp;quot;&amp;gt;[[#1foot|[1]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 int turn;  // turn for execution&lt;br /&gt;
 int interested[2];   // the processors interested&lt;br /&gt;
 void enter_region(int process) &lt;br /&gt;
 { &lt;br /&gt;
   int otherProcess; &lt;br /&gt;
   otherProcess = 1 - process;    &lt;br /&gt;
   interested[process]=1;  &lt;br /&gt;
   turn = process;         &lt;br /&gt;
   while(turn == process &amp;amp;&amp;amp; interested[otherProcess] == 1)&lt;br /&gt;
      {&lt;br /&gt;
  	// busy wait&lt;br /&gt;
      }&lt;br /&gt;
 } &lt;br /&gt;
 void leave_region(int process) &lt;br /&gt;
 { &lt;br /&gt;
   interested[process] = 0; &lt;br /&gt;
 }&lt;br /&gt;
The algorithm uses two variables as seen above, interested and turn.  If a flag value for interested is set to 1, it indicates the process wants to enter the critical section.  The variable turn is a placeholder for the process whose turn will be next allowed to enter the critical section.  As seen above, Process1 has been given priority over P0.&lt;br /&gt;
&lt;br /&gt;
To ensure mutual exclusion, the variable interested and turn are set to ensure only 1 can enter the critical section at a time.  To ensure Progress, once a processor has left the critical section the other processors can determine which processor is allowed into the critical section next.  To ensure bounded waiting, as seen with the above code, a process will wait no longer than 1 turn to enter the critical section as the variable turn=1 will be enabled.&lt;br /&gt;
&lt;br /&gt;
=Page tables=&lt;br /&gt;
An issue with multiprocessor systems is how to enter the critical section.  One software solution is to use Page tables to ensure mutual exclusion, progress, and bounded waiting which are the 3 criteria needed to be met&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;2body&amp;quot;&amp;gt;[[#2foot|[2]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Memory Coherence==&lt;br /&gt;
As with other forms of synchronization, page tables for multiprocessor systems must have strategies for handling data.  As discussed in Li and Hudaks article, there are two basic approaches for page synchronization, invalidation and write-broadcast.  In an invalidation approach, there is only 1 owner for each page, having either read or write access to the page.  In a write-broadcast, as the name implies, it broadcasts or writes all copies for the page data and returns the faulty instruction&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#3foot|[3]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
As mentioned in the invalidation approach, there must be an owner for the page.  There are two basic ownership approaches for page tables, fixed or dynamic.  In a fixed ownership approach, 1 processor always owns the same page.  Other processors who want read or write access to the page location must negotiate for the access.  For dynamic ownership, there are two subcategories, centralized or distributed management&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#3foot|[3]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Centralized Management==&lt;br /&gt;
In centralized management for dynamic pages, there is a single, central processor that maintains a page table which has a table for each page and each page has 3 fields: owner, copy set, and lock.  The owner field consists of the single processor which owns the page, which could also be thought as the most recent processor to have write access.  The copy set field has a list of all processors that have a copy of the page.  This field helps to avoid a broadcast.  The lock field is used for synchronizing requests&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#3foot|[3]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
==Distributed Management==&lt;br /&gt;
There are 2 schemes for Distributed Management: fixed and dynamic.  For a fixed distributed management, each processor in the system is given a predetermined subset of pages to manage.  A simple, straightforward distribution of responsibility is the divide pages evenly among the system, although there are other solutions which could be tailored to the applications needs&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#3foot|[3]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In a dynamic distributed management system, each processor keeps track of ownership of all pages within their local table.  Instead of the owner field in the Centralized Management scheme, instead there is a probOwner field which has the probable owner of the page for a page fault&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;3body&amp;quot;&amp;gt;[[#3foot|[3]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;1foot&amp;quot;&amp;gt;[[#1body|1.]]&amp;lt;/span&amp;gt; http://en.wikipedia.org/wiki/Memory_coherence  &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;2foot&amp;quot;&amp;gt;[[#2body|2.]]&amp;lt;/span&amp;gt; http://en.wikipedia.org/wiki/Peterson%27s_algorithm  &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;3foot&amp;quot;&amp;gt;[[#3body|3.]]&amp;lt;/span&amp;gt; Li, K. and Hudak, P. Memory Coherence in Shared Virtual Memory Systems. ACM Transactions on Computer Systems, 7(4):321{359, November 1989.  &amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Pmpatel</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_506_Spring_2011/ch6a_jp&amp;diff=43860</id>
		<title>CSC/ECE 506 Spring 2011/ch6a jp</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_506_Spring_2011/ch6a_jp&amp;diff=43860"/>
		<updated>2011-02-27T00:52:27Z</updated>

		<summary type="html">&lt;p&gt;Pmpatel: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Cache Hierarchy=&lt;br /&gt;
[[Image: memchart.jpg|thumbnail|right|Memory Hierarchy&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;9body&amp;quot;&amp;gt;[[#9foot|[9]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;]]&lt;br /&gt;
In a simple computer model, processor reads data and instructions from the memory and operates on the data.  Operating frequency of CPU increased faster than the speed of memory and memory interconnects.  For example, cores in Intel first generation i7 processors run at 3.2 GHz frequency, while the memory only runs at 1.3GHz frequency.  Also, multi-core architecture started putting more demand on memory bandwidth.  This increases the latency in memory access and CPU will have to be idle for most of the time.  Due to this, memory became a bottle neck in performance.   &lt;br /&gt;
&lt;br /&gt;
To solve this problem, “cache” was invented.  Cache is simply a temporary volatile storage space like primary memory but runs at the speed similar to core frequency.  CPU can access data and instructions from cache in few clock cycles while accessing data from main memory can take more than 50 cycles.  In early days of computing, cache was implemented as a stand alone chip outside the processor.  In today’s processors, cache is implemented on same die as core.  &lt;br /&gt;
&lt;br /&gt;
There can be multiple levels of caches, each cache subsequently away from the core and larger in size.  L1 is closest to the CPU and as a result, fastest to excess.  Next to L1 is L2 cache and then L3.  L1 cache is divided into instruction cache and data cache. This is better than having a combined larger cache as instruction cache being read-only is easy to implement while data cache is read-write.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| border='1' class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|+style=&amp;quot;white-space:nowrap&amp;quot;| Table 1: Cache on different Microprocessors&lt;br /&gt;
|-&lt;br /&gt;
! Company &amp;amp; Processor !! # cores !! L1 cache Per core !! L1 cache Per core !! L3 cache  !! Year&lt;br /&gt;
|-&lt;br /&gt;
| Intel Pentium Dual Core || 2 || I:32KB   D:32KB || 1MB 8 way set assoc.  || -  ||  2006&lt;br /&gt;
|-&lt;br /&gt;
| Intel Xeon Clovertown || 2 || I:4*32KB   D:4*32KB || 2*4MB || - || Jan 2007&lt;br /&gt;
|-&lt;br /&gt;
| Intel Xeon 3200 series || 4 || - || 2*4MB || - || Jan 2007&lt;br /&gt;
|-&lt;br /&gt;
| AMD Athlon 64FX || 2 || I:64KB     D:4KB  Both 2-way set assoc. || 1MB 16way set assoc. || - || Jan 2007&lt;br /&gt;
|-&lt;br /&gt;
| AMD Athlon 64X2 || 2 || I:64KB     D:4KB  Both 2-way set assoc. || 512KB/1MB 16way set assoc. || 2MB || Jan 2007&lt;br /&gt;
|-&lt;br /&gt;
| AMD Barcelona || 4 || I:64KB   D:64KB  || 512KB || 2MB Shared || Aug 2007&lt;br /&gt;
|-&lt;br /&gt;
| Sun Microsystems Ultra Sparc T2 || 8 ||  I:16KB   D:8KB || 4MB (8 banks) 16way set assoc. || - || Oct 2007&lt;br /&gt;
|-&lt;br /&gt;
| Intel Xeon Wolfdale DP || 2 ||  D:96KB  || 6MB || - || Nov 2007&lt;br /&gt;
|-&lt;br /&gt;
| Intel Xeon Hapertown || 4 ||  D:96KB  || 2*6MB || - || Nov 2007&lt;br /&gt;
|-&lt;br /&gt;
| AMD Phenom || 4 || I:64KB   D:64KB  || 512KB || 2MB Shared || Nov 2007    Mar 2008&lt;br /&gt;
|-&lt;br /&gt;
| Intel Core 2 Duo || 2 ||  I:32KB   D:32KB  || 2/4MB 8 way set assoc. || - ||  2008&lt;br /&gt;
|-&lt;br /&gt;
| Intel Penryn Wolfdale DP || 4 ||  -  || 6-12MB || 6MB || Mar 2008     Aug 2008&lt;br /&gt;
|-&lt;br /&gt;
| Intel Core 2 Quad Yorkfield || 4 ||  D:96KB  || 12MB  || - ||  Mar 2008&lt;br /&gt;
|-&lt;br /&gt;
| AMD Toliman || 3K10 || I:64KB   D:64KB  || 512KB || 2MB Shared || Apr 2008&lt;br /&gt;
|-&lt;br /&gt;
| Azul Systems Vega3 7300 Series || 864 || 768GB  || - || - || May 2008&lt;br /&gt;
|-&lt;br /&gt;
| IBM RoadRunner || 8+1 || 32KB  || 512KB || - || Jun 2008&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Cache Write Policies=&lt;br /&gt;
&lt;br /&gt;
==Write hit policies==&lt;br /&gt;
*Write-through: Also known as store-through, this policy will write to main memory whenever a write is performed to cache.&lt;br /&gt;
*Write-back: Also known as store-in or copy-back, this policy will write to main memory only when a block of data is purged from the cache storage.&lt;br /&gt;
&lt;br /&gt;
==Write miss policies==&lt;br /&gt;
*Write-allocate vs Write no-allocate: When a write misses in the cache, there may or may not be a line in the cache allocated to the block.  For write-allocate, there will be a line in the cache for the written data.  This policy is typically associated with write-back caches.  For no-write-allocate, there will not be a line in the cache.&lt;br /&gt;
*Fetch-on-write vs no-fetch-on-write: The fetch-on-write will cause the block of data to be fetched from a lower memory hierarchy if the write misses.  The policy fetches a block on every write miss.  &lt;br /&gt;
*Write-before-hit vs no-write-before-hit:  The write-before-hit will write data to the cache before checking the cache tags for a match.  In case of a miss, the policy will displace the block of data already in the cache.&lt;br /&gt;
&lt;br /&gt;
==Combination Policies==&lt;br /&gt;
* Write-validate: It is a combination of no-fetch-on-write and write-allocate&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;4body&amp;quot;&amp;gt;[[#4foot|[4]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.  The policy allows partial lines to be written to the cache on a miss.  It provides for better performance as well as works with machines that have various line sizes and does not add instruction execution overhead to the program being run.  Write-validate requires that the lower level system memory can support writes of partial lines.&lt;br /&gt;
* Write-invalidate: This policy is a combination of write-before-hit, no-fetch-on-write, and no-write-allocate&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;4body&amp;quot;&amp;gt;[[#4foot|[4]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.  This policy invalidates lines when there is a miss.&lt;br /&gt;
* Write-around:  Combination of no-fetch-on-write, no-write-allocate, and no-write-before-hit&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;4body&amp;quot;&amp;gt;[[#4foot|[4]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.  This policy uses a non-blocking write scheme to write to cache.  It writes data to the next lower cache without modifying the data of the cache line.&lt;br /&gt;
&lt;br /&gt;
=Prefetching=&lt;br /&gt;
Cache is very efficient in terms on access time once that data or instructions are in the cache.  But when a process tries to access something that is not already in the cache, a cache miss occurs and those pages need to be brought into the cache from memory.  Generally cache miss are expensive to the performance as the processor has to wait for that data (In parallel processing, a process can execute other tasks while it is waiting on data, but there will be some overhead for this).  Prefetching is a technique in which data is brought into cache before the program needs it.  In other words, it is a way to reduce cache misses.  Prefetching uses some type of prediction to mechanism to anticipate the next data that will be needed and brings them into cache.  It is not guaranteed that the perfected data will be used.  Goal here is to reduce cache misses to improve overall performance.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Some architectures have instructions to prefetch data into cache.  Programmers and compliers can insert this prefect instruction in the code.  This is known as software prefetching.  In hardware prefetching, processor observers the system behavior and issues requests for prefetching.  Intel 8086 and Motorola 68000 were the first microprocessors to implement instruction prefetch.   Graphics Processing Units benefit from prefetching due to spatial locality property of the data&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;8body&amp;quot;&amp;gt;[[#8foot|[8]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.   &lt;br /&gt;
&lt;br /&gt;
==Advantages==&lt;br /&gt;
*Improves overall performance by reducing cache misses.&lt;br /&gt;
==Disadvantages==&lt;br /&gt;
* Wastes bandwidth when prefetched data is not used.&lt;br /&gt;
* Hardware prefetching requires complex architecture.  Second order effect is cost of implementation on silicon and validation costs.&lt;br /&gt;
* Software prefetching adds additional instructions to the program, making the program larger.&lt;br /&gt;
* If same cache is used for prefetching, then prefetching could cause other cache blocks to be evicted.  If the evicted blocks are needed, then that will generate a cache miss.  This can be prevented by having a separate cache for prefetching but it comes with hardware costs.&lt;br /&gt;
* When scheduler changes the task running on a processor, prefetched data may become useless.&lt;br /&gt;
&lt;br /&gt;
==Effectiveness==&lt;br /&gt;
Prefetching effectiveness can be tracked by following matrices&lt;br /&gt;
# Coverage is defined as fraction of original cache misses that were prefetched resulting in cache hit.&lt;br /&gt;
# Accuracy is defined as fraction of prefetches that are useful.&lt;br /&gt;
# Timeliness measures how early the prefetches arrive.&lt;br /&gt;
Ideally, a system should have high coverage, high accuracy and optimum timeliness.  Realistically, aggressive prefetches can increase coverage but decrease accuracy and vice versa.  Also, if prefetching is done too early, the fetched data may have to be evicted without being used and if done too late, it can cause cache miss.&lt;br /&gt;
&lt;br /&gt;
==Stream Buffer Prefetching==&lt;br /&gt;
This is a technique for prefetching which uses a FIFO buffer in which each entry is a cacheline and has address (or tag) and a available bit.  System prefetches a stream of sequential data into a stream buffer and multiple stream buffers can be used to prefetch multiple streams in parallel.  On a cache access, head entries of stream buffers are check for match along with cache check. If the block is not found in cache but found at the head of stream buffer, it is moved to cache and next entry in the buffer becomes the head.  If the block is not found in cache or as head of buffer, data is brought from memory into cache and the subsequent address as assigned to a new stream buffer.   Only the heads of the stream buffers are checked during cache access and not the whole buffer.  Checking all the entries in all the buffers will increase hardware complexity.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 INSERT IMAGE HERE&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Above plot shows the cache hit improvements for with respect to number of stream buffers on different programs.  Graph on left compares 8 programs from NAS suite while graph on right shows programs from Unix unity suite&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;7body&amp;quot;&amp;gt;[[#7foot|[7]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.  &lt;br /&gt;
==Prefetching in Parallel Computing==&lt;br /&gt;
On a uniprocessor system, prefetching is definitely helpful to improve performance.  On a multiprocessor system prefetching is useful, but there are tighter constrains in implementing because of the fact that data will be shared between different processors or cores.  In message passing parallel model, each parallel thread has its own memory space and prefetching can be implemented in same way as for uniprocessor system.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
In shared memory parallel programming, multiple threads that run on different processors share common memory space.  If multiple processors use common cache, then prefetching implementation is similar to uniprocessor system.  Difficulties arise when each core has its own cache.  Some of the case-scenarios that can occur are:&lt;br /&gt;
# Processor P1 has prefetched some data D1 into its stream buffer but is not used it.  At the same time processor P2 reads data D1 into its cache and modifies it and one of the cache coherency protocols would be used to inform processor P1 about this change.  D1 is not in P1’s cache so it many simply ignore this.  Now, when P1 ties to read D1, it will get the stale data from its stream buffer.  One way to prevent this is by improving stream buffers so that they can modify their data just like a cache.  This adds complexity to the architecture and increases cost&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;6body&amp;quot;&amp;gt;[[#6foot|[6]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
# Prefetching mechanism can fetch data D1, D2, D3,….D10 into P1’s buffer.  Now due to parallel processing, P1 only needs to operate on D1 to D5 while P2 will operate on remaining data.  Some bandwidth was wasted in fetching D6 to D10 into P1 even though it did not use it.  There is a trade off to be made here, if prefetching is very conservative then it will lead to miss and if not then it will waste bandwidth.&lt;br /&gt;
# In a multiprocessor system, if threads are not bound to a core, Operation system can rebalance the treads of different cores.  This will require the prefetched buffers to be trashed.&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
&amp;lt;span id=&amp;quot;1foot&amp;quot;&amp;gt;[[#1body|1.]]&amp;lt;/span&amp;gt; http://www.real-knowledge.com/memory.htm  &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;2foot&amp;quot;&amp;gt;[[#2body|2.]]&amp;lt;/span&amp;gt; Computer Design &amp;amp; Technology- Lectures slides by Prof.Eric Rotenberg  &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;3foot&amp;quot;&amp;gt;[[#3body|3.]]&amp;lt;/span&amp;gt; Fundamentals of Parallel Computer Architecture by Prof.Yan Solihin  &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;4foot&amp;quot;&amp;gt;[[#4body|4.]]&amp;lt;/span&amp;gt; “Cache write policies and performance,” Norman Jouppi, Proc. 20th International Symposium on Computer Architecture (ACM Computer Architecture News 21:2), May 1993, pp. 191–201.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;5foot&amp;quot;&amp;gt;[[#5body|5.]]&amp;lt;/span&amp;gt; Architecture of Parallel Computers, Lecture slides by Prof. Edward Gehringer &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;6foot&amp;quot;&amp;gt;[[#6body|6.]]&amp;lt;/span&amp;gt; “Parallel computer architecture: a hardware/software approach” by David. E. Culler, Jaswinder Pal Singh, Anoop Gupta  (pg 887)    &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;7foot&amp;quot;&amp;gt;[[#7body|7.]]&amp;lt;/span&amp;gt; “Evaluating Stream Buffers as a Secondary Cache Replacement” by Subbarao Palacharla and R. E. Kessler.   (ref#2) &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;8foot&amp;quot;&amp;gt;[[#8body|8.]]&amp;lt;/span&amp;gt; http://en.wikipedia.org/wiki/Instruction_prefetch &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;9foot&amp;quot;&amp;gt;[[#9body|9.]]&amp;lt;/span&amp;gt; http://www.real-knowledge.com/memory.htm  &amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Pmpatel</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_506_Spring_2011/ch6a_jp&amp;diff=43859</id>
		<title>CSC/ECE 506 Spring 2011/ch6a jp</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_506_Spring_2011/ch6a_jp&amp;diff=43859"/>
		<updated>2011-02-27T00:51:47Z</updated>

		<summary type="html">&lt;p&gt;Pmpatel: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Cache Hierarchy=&lt;br /&gt;
[[Image: memchart.jpg|thumbnail|right|Memory Hierarchy&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;9body&amp;quot;&amp;gt;[[#9foot|[9]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;]]&lt;br /&gt;
In a simple computer model, processor reads data and instructions from the memory and operates on the data.  Operating frequency of CPU increased faster than the speed of memory and memory interconnects.  For example, cores in Intel first generation i7 processors run at 3.2 GHz frequency, while the memory only runs at 1.3GHz frequency.  Also, multi-core architecture started putting more demand on memory bandwidth.  This increases the latency in memory access and CPU will have to be idle for most of the time.  Due to this, memory became a bottle neck in performance.   &lt;br /&gt;
&lt;br /&gt;
To solve this problem, “cache” was invented.  Cache is simply a temporary volatile storage space like primary memory but runs at the speed similar to core frequency.  CPU can access data and instructions from cache in few clock cycles while accessing data from main memory can take more than 50 cycles.  In early days of computing, cache was implemented as a stand alone chip outside the processor.  In today’s processors, cache is implemented on same die as core.  &lt;br /&gt;
&lt;br /&gt;
There can be multiple levels of caches, each cache subsequently away from the core and larger in size.  L1 is closest to the CPU and as a result, fastest to excess.  Next to L1 is L2 cache and then L3.  L1 cache is divided into instruction cache and data cache. This is better than having a combined larger cache as instruction cache being read-only is easy to implement while data cache is read-write.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| border='1' class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|+style=&amp;quot;white-space:nowrap&amp;quot;| Processor Architecture&lt;br /&gt;
|-&lt;br /&gt;
! Company &amp;amp; Processor !! # cores !! L1 cache Per core !! L1 cache Per core !! L3 cache  !! Year&lt;br /&gt;
|-&lt;br /&gt;
| Intel Pentium Dual Core || 2 || I:32KB   D:32KB || 1MB 8 way set assoc.  || -  ||  2006&lt;br /&gt;
|-&lt;br /&gt;
| Intel Xeon Clovertown || 2 || I:4*32KB   D:4*32KB || 2*4MB || - || Jan 2007&lt;br /&gt;
|-&lt;br /&gt;
| Intel Xeon 3200 series || 4 || - || 2*4MB || - || Jan 2007&lt;br /&gt;
|-&lt;br /&gt;
| AMD Athlon 64FX || 2 || I:64KB     D:4KB  Both 2-way set assoc. || 1MB 16way set assoc. || - || Jan 2007&lt;br /&gt;
|-&lt;br /&gt;
| AMD Athlon 64X2 || 2 || I:64KB     D:4KB  Both 2-way set assoc. || 512KB/1MB 16way set assoc. || 2MB || Jan 2007&lt;br /&gt;
|-&lt;br /&gt;
| AMD Barcelona || 4 || I:64KB   D:64KB  || 512KB || 2MB Shared || Aug 2007&lt;br /&gt;
|-&lt;br /&gt;
| Sun Microsystems Ultra Sparc T2 || 8 ||  I:16KB   D:8KB || 4MB (8 banks) 16way set assoc. || - || Oct 2007&lt;br /&gt;
|-&lt;br /&gt;
| Intel Xeon Wolfdale DP || 2 ||  D:96KB  || 6MB || - || Nov 2007&lt;br /&gt;
|-&lt;br /&gt;
| Intel Xeon Hapertown || 4 ||  D:96KB  || 2*6MB || - || Nov 2007&lt;br /&gt;
|-&lt;br /&gt;
| AMD Phenom || 4 || I:64KB   D:64KB  || 512KB || 2MB Shared || Nov 2007    Mar 2008&lt;br /&gt;
|-&lt;br /&gt;
| Intel Core 2 Duo || 2 ||  I:32KB   D:32KB  || 2/4MB 8 way set assoc. || - ||  2008&lt;br /&gt;
|-&lt;br /&gt;
| Intel Penryn Wolfdale DP || 4 ||  -  || 6-12MB || 6MB || Mar 2008     Aug 2008&lt;br /&gt;
|-&lt;br /&gt;
| Intel Core 2 Quad Yorkfield || 4 ||  D:96KB  || 12MB  || - ||  Mar 2008&lt;br /&gt;
|-&lt;br /&gt;
| AMD Toliman || 3K10 || I:64KB   D:64KB  || 512KB || 2MB Shared || Apr 2008&lt;br /&gt;
|-&lt;br /&gt;
| Azul Systems Vega3 7300 Series || 864 || 768GB  || - || - || May 2008&lt;br /&gt;
|-&lt;br /&gt;
| IBM RoadRunner || 8+1 || 32KB  || 512KB || - || Jun 2008&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Cache Write Policies=&lt;br /&gt;
&lt;br /&gt;
==Write hit policies==&lt;br /&gt;
*Write-through: Also known as store-through, this policy will write to main memory whenever a write is performed to cache.&lt;br /&gt;
*Write-back: Also known as store-in or copy-back, this policy will write to main memory only when a block of data is purged from the cache storage.&lt;br /&gt;
&lt;br /&gt;
==Write miss policies==&lt;br /&gt;
*Write-allocate vs Write no-allocate: When a write misses in the cache, there may or may not be a line in the cache allocated to the block.  For write-allocate, there will be a line in the cache for the written data.  This policy is typically associated with write-back caches.  For no-write-allocate, there will not be a line in the cache.&lt;br /&gt;
*Fetch-on-write vs no-fetch-on-write: The fetch-on-write will cause the block of data to be fetched from a lower memory hierarchy if the write misses.  The policy fetches a block on every write miss.  &lt;br /&gt;
*Write-before-hit vs no-write-before-hit:  The write-before-hit will write data to the cache before checking the cache tags for a match.  In case of a miss, the policy will displace the block of data already in the cache.&lt;br /&gt;
&lt;br /&gt;
==Combination Policies==&lt;br /&gt;
* Write-validate: It is a combination of no-fetch-on-write and write-allocate&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;4body&amp;quot;&amp;gt;[[#4foot|[4]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.  The policy allows partial lines to be written to the cache on a miss.  It provides for better performance as well as works with machines that have various line sizes and does not add instruction execution overhead to the program being run.  Write-validate requires that the lower level system memory can support writes of partial lines.&lt;br /&gt;
* Write-invalidate: This policy is a combination of write-before-hit, no-fetch-on-write, and no-write-allocate&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;4body&amp;quot;&amp;gt;[[#4foot|[4]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.  This policy invalidates lines when there is a miss.&lt;br /&gt;
* Write-around:  Combination of no-fetch-on-write, no-write-allocate, and no-write-before-hit&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;4body&amp;quot;&amp;gt;[[#4foot|[4]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.  This policy uses a non-blocking write scheme to write to cache.  It writes data to the next lower cache without modifying the data of the cache line.&lt;br /&gt;
&lt;br /&gt;
=Prefetching=&lt;br /&gt;
Cache is very efficient in terms on access time once that data or instructions are in the cache.  But when a process tries to access something that is not already in the cache, a cache miss occurs and those pages need to be brought into the cache from memory.  Generally cache miss are expensive to the performance as the processor has to wait for that data (In parallel processing, a process can execute other tasks while it is waiting on data, but there will be some overhead for this).  Prefetching is a technique in which data is brought into cache before the program needs it.  In other words, it is a way to reduce cache misses.  Prefetching uses some type of prediction to mechanism to anticipate the next data that will be needed and brings them into cache.  It is not guaranteed that the perfected data will be used.  Goal here is to reduce cache misses to improve overall performance.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Some architectures have instructions to prefetch data into cache.  Programmers and compliers can insert this prefect instruction in the code.  This is known as software prefetching.  In hardware prefetching, processor observers the system behavior and issues requests for prefetching.  Intel 8086 and Motorola 68000 were the first microprocessors to implement instruction prefetch.   Graphics Processing Units benefit from prefetching due to spatial locality property of the data&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;8body&amp;quot;&amp;gt;[[#8foot|[8]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.   &lt;br /&gt;
&lt;br /&gt;
==Advantages==&lt;br /&gt;
*Improves overall performance by reducing cache misses.&lt;br /&gt;
==Disadvantages==&lt;br /&gt;
* Wastes bandwidth when prefetched data is not used.&lt;br /&gt;
* Hardware prefetching requires complex architecture.  Second order effect is cost of implementation on silicon and validation costs.&lt;br /&gt;
* Software prefetching adds additional instructions to the program, making the program larger.&lt;br /&gt;
* If same cache is used for prefetching, then prefetching could cause other cache blocks to be evicted.  If the evicted blocks are needed, then that will generate a cache miss.  This can be prevented by having a separate cache for prefetching but it comes with hardware costs.&lt;br /&gt;
* When scheduler changes the task running on a processor, prefetched data may become useless.&lt;br /&gt;
&lt;br /&gt;
==Effectiveness==&lt;br /&gt;
Prefetching effectiveness can be tracked by following matrices&lt;br /&gt;
# Coverage is defined as fraction of original cache misses that were prefetched resulting in cache hit.&lt;br /&gt;
# Accuracy is defined as fraction of prefetches that are useful.&lt;br /&gt;
# Timeliness measures how early the prefetches arrive.&lt;br /&gt;
Ideally, a system should have high coverage, high accuracy and optimum timeliness.  Realistically, aggressive prefetches can increase coverage but decrease accuracy and vice versa.  Also, if prefetching is done too early, the fetched data may have to be evicted without being used and if done too late, it can cause cache miss.&lt;br /&gt;
&lt;br /&gt;
==Stream Buffer Prefetching==&lt;br /&gt;
This is a technique for prefetching which uses a FIFO buffer in which each entry is a cacheline and has address (or tag) and a available bit.  System prefetches a stream of sequential data into a stream buffer and multiple stream buffers can be used to prefetch multiple streams in parallel.  On a cache access, head entries of stream buffers are check for match along with cache check. If the block is not found in cache but found at the head of stream buffer, it is moved to cache and next entry in the buffer becomes the head.  If the block is not found in cache or as head of buffer, data is brought from memory into cache and the subsequent address as assigned to a new stream buffer.   Only the heads of the stream buffers are checked during cache access and not the whole buffer.  Checking all the entries in all the buffers will increase hardware complexity.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 INSERT IMAGE HERE&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Above plot shows the cache hit improvements for with respect to number of stream buffers on different programs.  Graph on left compares 8 programs from NAS suite while graph on right shows programs from Unix unity suite&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;7body&amp;quot;&amp;gt;[[#7foot|[7]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.  &lt;br /&gt;
==Prefetching in Parallel Computing==&lt;br /&gt;
On a uniprocessor system, prefetching is definitely helpful to improve performance.  On a multiprocessor system prefetching is useful, but there are tighter constrains in implementing because of the fact that data will be shared between different processors or cores.  In message passing parallel model, each parallel thread has its own memory space and prefetching can be implemented in same way as for uniprocessor system.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
In shared memory parallel programming, multiple threads that run on different processors share common memory space.  If multiple processors use common cache, then prefetching implementation is similar to uniprocessor system.  Difficulties arise when each core has its own cache.  Some of the case-scenarios that can occur are:&lt;br /&gt;
# Processor P1 has prefetched some data D1 into its stream buffer but is not used it.  At the same time processor P2 reads data D1 into its cache and modifies it and one of the cache coherency protocols would be used to inform processor P1 about this change.  D1 is not in P1’s cache so it many simply ignore this.  Now, when P1 ties to read D1, it will get the stale data from its stream buffer.  One way to prevent this is by improving stream buffers so that they can modify their data just like a cache.  This adds complexity to the architecture and increases cost&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;6body&amp;quot;&amp;gt;[[#6foot|[6]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
# Prefetching mechanism can fetch data D1, D2, D3,….D10 into P1’s buffer.  Now due to parallel processing, P1 only needs to operate on D1 to D5 while P2 will operate on remaining data.  Some bandwidth was wasted in fetching D6 to D10 into P1 even though it did not use it.  There is a trade off to be made here, if prefetching is very conservative then it will lead to miss and if not then it will waste bandwidth.&lt;br /&gt;
# In a multiprocessor system, if threads are not bound to a core, Operation system can rebalance the treads of different cores.  This will require the prefetched buffers to be trashed.&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
&amp;lt;span id=&amp;quot;1foot&amp;quot;&amp;gt;[[#1body|1.]]&amp;lt;/span&amp;gt; http://www.real-knowledge.com/memory.htm  &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;2foot&amp;quot;&amp;gt;[[#2body|2.]]&amp;lt;/span&amp;gt; Computer Design &amp;amp; Technology- Lectures slides by Prof.Eric Rotenberg  &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;3foot&amp;quot;&amp;gt;[[#3body|3.]]&amp;lt;/span&amp;gt; Fundamentals of Parallel Computer Architecture by Prof.Yan Solihin  &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;4foot&amp;quot;&amp;gt;[[#4body|4.]]&amp;lt;/span&amp;gt; “Cache write policies and performance,” Norman Jouppi, Proc. 20th International Symposium on Computer Architecture (ACM Computer Architecture News 21:2), May 1993, pp. 191–201.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;5foot&amp;quot;&amp;gt;[[#5body|5.]]&amp;lt;/span&amp;gt; Architecture of Parallel Computers, Lecture slides by Prof. Edward Gehringer &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;6foot&amp;quot;&amp;gt;[[#6body|6.]]&amp;lt;/span&amp;gt; “Parallel computer architecture: a hardware/software approach” by David. E. Culler, Jaswinder Pal Singh, Anoop Gupta  (pg 887)    &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;7foot&amp;quot;&amp;gt;[[#7body|7.]]&amp;lt;/span&amp;gt; “Evaluating Stream Buffers as a Secondary Cache Replacement” by Subbarao Palacharla and R. E. Kessler.   (ref#2) &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;8foot&amp;quot;&amp;gt;[[#8body|8.]]&amp;lt;/span&amp;gt; http://en.wikipedia.org/wiki/Instruction_prefetch &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;9foot&amp;quot;&amp;gt;[[#9body|9.]]&amp;lt;/span&amp;gt; http://www.real-knowledge.com/memory.htm  &amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Pmpatel</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_506_Spring_2011/ch6a_jp&amp;diff=43858</id>
		<title>CSC/ECE 506 Spring 2011/ch6a jp</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_506_Spring_2011/ch6a_jp&amp;diff=43858"/>
		<updated>2011-02-27T00:51:08Z</updated>

		<summary type="html">&lt;p&gt;Pmpatel: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Cache Hierarchy=&lt;br /&gt;
[[Image: memchart.jpg|thumbnail|right|Memory Hierarchy&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;9body&amp;quot;&amp;gt;[[#9foot|[9]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;]]&lt;br /&gt;
In a simple computer model, processor reads data and instructions from the memory and operates on the data.  Operating frequency of CPU increased faster than the speed of memory and memory interconnects.  For example, cores in Intel first generation i7 processors run at 3.2 GHz frequency, while the memory only runs at 1.3GHz frequency.  Also, multi-core architecture started putting more demand on memory bandwidth.  This increases the latency in memory access and CPU will have to be idle for most of the time.  Due to this, memory became a bottle neck in performance.   &lt;br /&gt;
&lt;br /&gt;
To solve this problem, “cache” was invented.  Cache is simply a temporary volatile storage space like primary memory but runs at the speed similar to core frequency.  CPU can access data and instructions from cache in few clock cycles while accessing data from main memory can take more than 50 cycles.  In early days of computing, cache was implemented as a stand alone chip outside the processor.  In today’s processors, cache is implemented on same die as core.  &lt;br /&gt;
&lt;br /&gt;
There can be multiple levels of caches, each cache subsequently away from the core and larger in size.  L1 is closest to the CPU and as a result, fastest to excess.  Next to L1 is L2 cache and then L3.  L1 cache is divided into instruction cache and data cache. This is better than having a combined larger cache as instruction cache being read-only is easy to implement while data cache is read-write.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Cache Write Policies=&lt;br /&gt;
&lt;br /&gt;
==Write hit policies==&lt;br /&gt;
*Write-through: Also known as store-through, this policy will write to main memory whenever a write is performed to cache.&lt;br /&gt;
*Write-back: Also known as store-in or copy-back, this policy will write to main memory only when a block of data is purged from the cache storage.&lt;br /&gt;
&lt;br /&gt;
==Write miss policies==&lt;br /&gt;
*Write-allocate vs Write no-allocate: When a write misses in the cache, there may or may not be a line in the cache allocated to the block.  For write-allocate, there will be a line in the cache for the written data.  This policy is typically associated with write-back caches.  For no-write-allocate, there will not be a line in the cache.&lt;br /&gt;
*Fetch-on-write vs no-fetch-on-write: The fetch-on-write will cause the block of data to be fetched from a lower memory hierarchy if the write misses.  The policy fetches a block on every write miss.  &lt;br /&gt;
*Write-before-hit vs no-write-before-hit:  The write-before-hit will write data to the cache before checking the cache tags for a match.  In case of a miss, the policy will displace the block of data already in the cache.&lt;br /&gt;
&lt;br /&gt;
==Combination Policies==&lt;br /&gt;
* Write-validate: It is a combination of no-fetch-on-write and write-allocate&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;4body&amp;quot;&amp;gt;[[#4foot|[4]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.  The policy allows partial lines to be written to the cache on a miss.  It provides for better performance as well as works with machines that have various line sizes and does not add instruction execution overhead to the program being run.  Write-validate requires that the lower level system memory can support writes of partial lines.&lt;br /&gt;
* Write-invalidate: This policy is a combination of write-before-hit, no-fetch-on-write, and no-write-allocate&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;4body&amp;quot;&amp;gt;[[#4foot|[4]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.  This policy invalidates lines when there is a miss.&lt;br /&gt;
* Write-around:  Combination of no-fetch-on-write, no-write-allocate, and no-write-before-hit&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;4body&amp;quot;&amp;gt;[[#4foot|[4]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.  This policy uses a non-blocking write scheme to write to cache.  It writes data to the next lower cache without modifying the data of the cache line.&lt;br /&gt;
&lt;br /&gt;
=Prefetching=&lt;br /&gt;
Cache is very efficient in terms on access time once that data or instructions are in the cache.  But when a process tries to access something that is not already in the cache, a cache miss occurs and those pages need to be brought into the cache from memory.  Generally cache miss are expensive to the performance as the processor has to wait for that data (In parallel processing, a process can execute other tasks while it is waiting on data, but there will be some overhead for this).  Prefetching is a technique in which data is brought into cache before the program needs it.  In other words, it is a way to reduce cache misses.  Prefetching uses some type of prediction to mechanism to anticipate the next data that will be needed and brings them into cache.  It is not guaranteed that the perfected data will be used.  Goal here is to reduce cache misses to improve overall performance.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Some architectures have instructions to prefetch data into cache.  Programmers and compliers can insert this prefect instruction in the code.  This is known as software prefetching.  In hardware prefetching, processor observers the system behavior and issues requests for prefetching.  Intel 8086 and Motorola 68000 were the first microprocessors to implement instruction prefetch.   Graphics Processing Units benefit from prefetching due to spatial locality property of the data&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;8body&amp;quot;&amp;gt;[[#8foot|[8]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.   &lt;br /&gt;
&lt;br /&gt;
==Advantages==&lt;br /&gt;
*Improves overall performance by reducing cache misses.&lt;br /&gt;
==Disadvantages==&lt;br /&gt;
* Wastes bandwidth when prefetched data is not used.&lt;br /&gt;
* Hardware prefetching requires complex architecture.  Second order effect is cost of implementation on silicon and validation costs.&lt;br /&gt;
* Software prefetching adds additional instructions to the program, making the program larger.&lt;br /&gt;
* If same cache is used for prefetching, then prefetching could cause other cache blocks to be evicted.  If the evicted blocks are needed, then that will generate a cache miss.  This can be prevented by having a separate cache for prefetching but it comes with hardware costs.&lt;br /&gt;
* When scheduler changes the task running on a processor, prefetched data may become useless.&lt;br /&gt;
&lt;br /&gt;
==Effectiveness==&lt;br /&gt;
Prefetching effectiveness can be tracked by following matrices&lt;br /&gt;
# Coverage is defined as fraction of original cache misses that were prefetched resulting in cache hit.&lt;br /&gt;
# Accuracy is defined as fraction of prefetches that are useful.&lt;br /&gt;
# Timeliness measures how early the prefetches arrive.&lt;br /&gt;
Ideally, a system should have high coverage, high accuracy and optimum timeliness.  Realistically, aggressive prefetches can increase coverage but decrease accuracy and vice versa.  Also, if prefetching is done too early, the fetched data may have to be evicted without being used and if done too late, it can cause cache miss.&lt;br /&gt;
&lt;br /&gt;
==Stream Buffer Prefetching==&lt;br /&gt;
This is a technique for prefetching which uses a FIFO buffer in which each entry is a cacheline and has address (or tag) and a available bit.  System prefetches a stream of sequential data into a stream buffer and multiple stream buffers can be used to prefetch multiple streams in parallel.  On a cache access, head entries of stream buffers are check for match along with cache check. If the block is not found in cache but found at the head of stream buffer, it is moved to cache and next entry in the buffer becomes the head.  If the block is not found in cache or as head of buffer, data is brought from memory into cache and the subsequent address as assigned to a new stream buffer.   Only the heads of the stream buffers are checked during cache access and not the whole buffer.  Checking all the entries in all the buffers will increase hardware complexity.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 INSERT IMAGE HERE&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Above plot shows the cache hit improvements for with respect to number of stream buffers on different programs.  Graph on left compares 8 programs from NAS suite while graph on right shows programs from Unix unity suite&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;7body&amp;quot;&amp;gt;[[#7foot|[7]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.  &lt;br /&gt;
==Prefetching in Parallel Computing==&lt;br /&gt;
On a uniprocessor system, prefetching is definitely helpful to improve performance.  On a multiprocessor system prefetching is useful, but there are tighter constrains in implementing because of the fact that data will be shared between different processors or cores.  In message passing parallel model, each parallel thread has its own memory space and prefetching can be implemented in same way as for uniprocessor system.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
In shared memory parallel programming, multiple threads that run on different processors share common memory space.  If multiple processors use common cache, then prefetching implementation is similar to uniprocessor system.  Difficulties arise when each core has its own cache.  Some of the case-scenarios that can occur are:&lt;br /&gt;
# Processor P1 has prefetched some data D1 into its stream buffer but is not used it.  At the same time processor P2 reads data D1 into its cache and modifies it and one of the cache coherency protocols would be used to inform processor P1 about this change.  D1 is not in P1’s cache so it many simply ignore this.  Now, when P1 ties to read D1, it will get the stale data from its stream buffer.  One way to prevent this is by improving stream buffers so that they can modify their data just like a cache.  This adds complexity to the architecture and increases cost&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;6body&amp;quot;&amp;gt;[[#6foot|[6]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
# Prefetching mechanism can fetch data D1, D2, D3,….D10 into P1’s buffer.  Now due to parallel processing, P1 only needs to operate on D1 to D5 while P2 will operate on remaining data.  Some bandwidth was wasted in fetching D6 to D10 into P1 even though it did not use it.  There is a trade off to be made here, if prefetching is very conservative then it will lead to miss and if not then it will waste bandwidth.&lt;br /&gt;
# In a multiprocessor system, if threads are not bound to a core, Operation system can rebalance the treads of different cores.  This will require the prefetched buffers to be trashed.&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
&amp;lt;span id=&amp;quot;1foot&amp;quot;&amp;gt;[[#1body|1.]]&amp;lt;/span&amp;gt; http://www.real-knowledge.com/memory.htm  &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;2foot&amp;quot;&amp;gt;[[#2body|2.]]&amp;lt;/span&amp;gt; Computer Design &amp;amp; Technology- Lectures slides by Prof.Eric Rotenberg  &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;3foot&amp;quot;&amp;gt;[[#3body|3.]]&amp;lt;/span&amp;gt; Fundamentals of Parallel Computer Architecture by Prof.Yan Solihin  &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;4foot&amp;quot;&amp;gt;[[#4body|4.]]&amp;lt;/span&amp;gt; “Cache write policies and performance,” Norman Jouppi, Proc. 20th International Symposium on Computer Architecture (ACM Computer Architecture News 21:2), May 1993, pp. 191–201.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;5foot&amp;quot;&amp;gt;[[#5body|5.]]&amp;lt;/span&amp;gt; Architecture of Parallel Computers, Lecture slides by Prof. Edward Gehringer &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;6foot&amp;quot;&amp;gt;[[#6body|6.]]&amp;lt;/span&amp;gt; “Parallel computer architecture: a hardware/software approach” by David. E. Culler, Jaswinder Pal Singh, Anoop Gupta  (pg 887)    &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;7foot&amp;quot;&amp;gt;[[#7body|7.]]&amp;lt;/span&amp;gt; “Evaluating Stream Buffers as a Secondary Cache Replacement” by Subbarao Palacharla and R. E. Kessler.   (ref#2) &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;8foot&amp;quot;&amp;gt;[[#8body|8.]]&amp;lt;/span&amp;gt; http://en.wikipedia.org/wiki/Instruction_prefetch &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;9foot&amp;quot;&amp;gt;[[#9body|9.]]&amp;lt;/span&amp;gt; http://www.real-knowledge.com/memory.htm  &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| border='1' class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|+style=&amp;quot;white-space:nowrap&amp;quot;| Processor Architecture&lt;br /&gt;
|-&lt;br /&gt;
! Company &amp;amp; Processor !! # cores !! L1 cache Per core !! L1 cache Per core !! L3 cache  !! Year&lt;br /&gt;
|-&lt;br /&gt;
| Intel Pentium Dual Core || 2 || I:32KB   D:32KB || 1MB 8 way set assoc.  || -  ||  2006&lt;br /&gt;
|-&lt;br /&gt;
| Intel Xeon Clovertown || 2 || I:4*32KB   D:4*32KB || 2*4MB || - || Jan 2007&lt;br /&gt;
|-&lt;br /&gt;
| Intel Xeon 3200 series || 4 || - || 2*4MB || - || Jan 2007&lt;br /&gt;
|-&lt;br /&gt;
| AMD Athlon 64FX || 2 || I:64KB     D:4KB  Both 2-way set assoc. || 1MB 16way set assoc. || - || Jan 2007&lt;br /&gt;
|-&lt;br /&gt;
| AMD Athlon 64X2 || 2 || I:64KB     D:4KB  Both 2-way set assoc. || 512KB/1MB 16way set assoc. || 2MB || Jan 2007&lt;br /&gt;
|-&lt;br /&gt;
| AMD Barcelona || 4 || I:64KB   D:64KB  || 512KB || 2MB Shared || Aug 2007&lt;br /&gt;
|-&lt;br /&gt;
| Sun Microsystems Ultra Sparc T2 || 8 ||  I:16KB   D:8KB || 4MB (8 banks) 16way set assoc. || - || Oct 2007&lt;br /&gt;
|-&lt;br /&gt;
| Intel Xeon Wolfdale DP || 2 ||  D:96KB  || 6MB || - || Nov 2007&lt;br /&gt;
|-&lt;br /&gt;
| Intel Xeon Hapertown || 4 ||  D:96KB  || 2*6MB || - || Nov 2007&lt;br /&gt;
|-&lt;br /&gt;
| AMD Phenom || 4 || I:64KB   D:64KB  || 512KB || 2MB Shared || Nov 2007    Mar 2008&lt;br /&gt;
|-&lt;br /&gt;
| Intel Core 2 Duo || 2 ||  I:32KB   D:32KB  || 2/4MB 8 way set assoc. || - ||  2008&lt;br /&gt;
|-&lt;br /&gt;
| Intel Penryn Wolfdale DP || 4 ||  -  || 6-12MB || 6MB || Mar 2008     Aug 2008&lt;br /&gt;
|-&lt;br /&gt;
| Intel Core 2 Quad Yorkfield || 4 ||  D:96KB  || 12MB  || - ||  Mar 2008&lt;br /&gt;
|-&lt;br /&gt;
| AMD Toliman || 3K10 || I:64KB   D:64KB  || 512KB || 2MB Shared || Apr 2008&lt;br /&gt;
|-&lt;br /&gt;
| Azul Systems Vega3 7300 Series || 864 || 768GB  || - || - || May 2008&lt;br /&gt;
|-&lt;br /&gt;
| IBM RoadRunner || 8+1 || 32KB  || 512KB || - || Jun 2008&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Pmpatel</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_506_Spring_2011/ch6a_jp&amp;diff=43857</id>
		<title>CSC/ECE 506 Spring 2011/ch6a jp</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_506_Spring_2011/ch6a_jp&amp;diff=43857"/>
		<updated>2011-02-27T00:49:55Z</updated>

		<summary type="html">&lt;p&gt;Pmpatel: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Cache Hierarchy=&lt;br /&gt;
[[Image: memchart.jpg|thumbnail|right|Memory Hierarchy&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;9body&amp;quot;&amp;gt;[[#9foot|[9]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;]]&lt;br /&gt;
In a simple computer model, processor reads data and instructions from the memory and operates on the data.  Operating frequency of CPU increased faster than the speed of memory and memory interconnects.  For example, cores in Intel first generation i7 processors run at 3.2 GHz frequency, while the memory only runs at 1.3GHz frequency.  Also, multi-core architecture started putting more demand on memory bandwidth.  This increases the latency in memory access and CPU will have to be idle for most of the time.  Due to this, memory became a bottle neck in performance.   &lt;br /&gt;
&lt;br /&gt;
To solve this problem, “cache” was invented.  Cache is simply a temporary volatile storage space like primary memory but runs at the speed similar to core frequency.  CPU can access data and instructions from cache in few clock cycles while accessing data from main memory can take more than 50 cycles.  In early days of computing, cache was implemented as a stand alone chip outside the processor.  In today’s processors, cache is implemented on same die as core.  &lt;br /&gt;
&lt;br /&gt;
There can be multiple levels of caches, each cache subsequently away from the core and larger in size.  L1 is closest to the CPU and as a result, fastest to excess.  Next to L1 is L2 cache and then L3.  L1 cache is divided into instruction cache and data cache. This is better than having a combined larger cache as instruction cache being read-only is easy to implement while data cache is read-write.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Cache Write Policies=&lt;br /&gt;
&lt;br /&gt;
==Write hit policies==&lt;br /&gt;
*Write-through: Also known as store-through, this policy will write to main memory whenever a write is performed to cache.&lt;br /&gt;
*Write-back: Also known as store-in or copy-back, this policy will write to main memory only when a block of data is purged from the cache storage.&lt;br /&gt;
&lt;br /&gt;
==Write miss policies==&lt;br /&gt;
*Write-allocate vs Write no-allocate: When a write misses in the cache, there may or may not be a line in the cache allocated to the block.  For write-allocate, there will be a line in the cache for the written data.  This policy is typically associated with write-back caches.  For no-write-allocate, there will not be a line in the cache.&lt;br /&gt;
*Fetch-on-write vs no-fetch-on-write: The fetch-on-write will cause the block of data to be fetched from a lower memory hierarchy if the write misses.  The policy fetches a block on every write miss.  &lt;br /&gt;
*Write-before-hit vs no-write-before-hit:  The write-before-hit will write data to the cache before checking the cache tags for a match.  In case of a miss, the policy will displace the block of data already in the cache.&lt;br /&gt;
&lt;br /&gt;
==Combination Policies==&lt;br /&gt;
* Write-validate: It is a combination of no-fetch-on-write and write-allocate&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;4body&amp;quot;&amp;gt;[[#4foot|[4]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.  The policy allows partial lines to be written to the cache on a miss.  It provides for better performance as well as works with machines that have various line sizes and does not add instruction execution overhead to the program being run.  Write-validate requires that the lower level system memory can support writes of partial lines.&lt;br /&gt;
* Write-invalidate: This policy is a combination of write-before-hit, no-fetch-on-write, and no-write-allocate&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;4body&amp;quot;&amp;gt;[[#4foot|[4]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.  This policy invalidates lines when there is a miss.&lt;br /&gt;
* Write-around:  Combination of no-fetch-on-write, no-write-allocate, and no-write-before-hit&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;4body&amp;quot;&amp;gt;[[#4foot|[4]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.  This policy uses a non-blocking write scheme to write to cache.  It writes data to the next lower cache without modifying the data of the cache line.&lt;br /&gt;
&lt;br /&gt;
=Prefetching=&lt;br /&gt;
Cache is very efficient in terms on access time once that data or instructions are in the cache.  But when a process tries to access something that is not already in the cache, a cache miss occurs and those pages need to be brought into the cache from memory.  Generally cache miss are expensive to the performance as the processor has to wait for that data (In parallel processing, a process can execute other tasks while it is waiting on data, but there will be some overhead for this).  Prefetching is a technique in which data is brought into cache before the program needs it.  In other words, it is a way to reduce cache misses.  Prefetching uses some type of prediction to mechanism to anticipate the next data that will be needed and brings them into cache.  It is not guaranteed that the perfected data will be used.  Goal here is to reduce cache misses to improve overall performance.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Some architectures have instructions to prefetch data into cache.  Programmers and compliers can insert this prefect instruction in the code.  This is known as software prefetching.  In hardware prefetching, processor observers the system behavior and issues requests for prefetching.  Intel 8086 and Motorola 68000 were the first microprocessors to implement instruction prefetch.   Graphics Processing Units benefit from prefetching due to spatial locality property of the data&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;8body&amp;quot;&amp;gt;[[#8foot|[8]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.   &lt;br /&gt;
&lt;br /&gt;
==Advantages==&lt;br /&gt;
*Improves overall performance by reducing cache misses.&lt;br /&gt;
==Disadvantages==&lt;br /&gt;
* Wastes bandwidth when prefetched data is not used.&lt;br /&gt;
* Hardware prefetching requires complex architecture.  Second order effect is cost of implementation on silicon and validation costs.&lt;br /&gt;
* Software prefetching adds additional instructions to the program, making the program larger.&lt;br /&gt;
* If same cache is used for prefetching, then prefetching could cause other cache blocks to be evicted.  If the evicted blocks are needed, then that will generate a cache miss.  This can be prevented by having a separate cache for prefetching but it comes with hardware costs.&lt;br /&gt;
* When scheduler changes the task running on a processor, prefetched data may become useless.&lt;br /&gt;
&lt;br /&gt;
==Effectiveness==&lt;br /&gt;
Prefetching effectiveness can be tracked by following matrices&lt;br /&gt;
# Coverage is defined as fraction of original cache misses that were prefetched resulting in cache hit.&lt;br /&gt;
# Accuracy is defined as fraction of prefetches that are useful.&lt;br /&gt;
# Timeliness measures how early the prefetches arrive.&lt;br /&gt;
Ideally, a system should have high coverage, high accuracy and optimum timeliness.  Realistically, aggressive prefetches can increase coverage but decrease accuracy and vice versa.  Also, if prefetching is done too early, the fetched data may have to be evicted without being used and if done too late, it can cause cache miss.&lt;br /&gt;
&lt;br /&gt;
==Stream Buffer Prefetching==&lt;br /&gt;
This is a technique for prefetching which uses a FIFO buffer in which each entry is a cacheline and has address (or tag) and a available bit.  System prefetches a stream of sequential data into a stream buffer and multiple stream buffers can be used to prefetch multiple streams in parallel.  On a cache access, head entries of stream buffers are check for match along with cache check. If the block is not found in cache but found at the head of stream buffer, it is moved to cache and next entry in the buffer becomes the head.  If the block is not found in cache or as head of buffer, data is brought from memory into cache and the subsequent address as assigned to a new stream buffer.   Only the heads of the stream buffers are checked during cache access and not the whole buffer.  Checking all the entries in all the buffers will increase hardware complexity.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 INSERT IMAGE HERE&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Above plot shows the cache hit improvements for with respect to number of stream buffers on different programs.  Graph on left compares 8 programs from NAS suite while graph on right shows programs from Unix unity suite&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;7body&amp;quot;&amp;gt;[[#7foot|[7]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.  &lt;br /&gt;
==Prefetching in Parallel Computing==&lt;br /&gt;
On a uniprocessor system, prefetching is definitely helpful to improve performance.  On a multiprocessor system prefetching is useful, but there are tighter constrains in implementing because of the fact that data will be shared between different processors or cores.  In message passing parallel model, each parallel thread has its own memory space and prefetching can be implemented in same way as for uniprocessor system.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
In shared memory parallel programming, multiple threads that run on different processors share common memory space.  If multiple processors use common cache, then prefetching implementation is similar to uniprocessor system.  Difficulties arise when each core has its own cache.  Some of the case-scenarios that can occur are:&lt;br /&gt;
# Processor P1 has prefetched some data D1 into its stream buffer but is not used it.  At the same time processor P2 reads data D1 into its cache and modifies it and one of the cache coherency protocols would be used to inform processor P1 about this change.  D1 is not in P1’s cache so it many simply ignore this.  Now, when P1 ties to read D1, it will get the stale data from its stream buffer.  One way to prevent this is by improving stream buffers so that they can modify their data just like a cache.  This adds complexity to the architecture and increases cost&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;6body&amp;quot;&amp;gt;[[#6foot|[6]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
# Prefetching mechanism can fetch data D1, D2, D3,….D10 into P1’s buffer.  Now due to parallel processing, P1 only needs to operate on D1 to D5 while P2 will operate on remaining data.  Some bandwidth was wasted in fetching D6 to D10 into P1 even though it did not use it.  There is a trade off to be made here, if prefetching is very conservative then it will lead to miss and if not then it will waste bandwidth.&lt;br /&gt;
# In a multiprocessor system, if threads are not bound to a core, Operation system can rebalance the treads of different cores.  This will require the prefetched buffers to be trashed.&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
&amp;lt;span id=&amp;quot;1foot&amp;quot;&amp;gt;[[#1body|1.]]&amp;lt;/span&amp;gt; http://www.real-knowledge.com/memory.htm  &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;2foot&amp;quot;&amp;gt;[[#2body|2.]]&amp;lt;/span&amp;gt; Computer Design &amp;amp; Technology- Lectures slides by Prof.Eric Rotenberg  &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;3foot&amp;quot;&amp;gt;[[#3body|3.]]&amp;lt;/span&amp;gt; Fundamentals of Parallel Computer Architecture by Prof.Yan Solihin  &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;4foot&amp;quot;&amp;gt;[[#4body|4.]]&amp;lt;/span&amp;gt; “Cache write policies and performance,” Norman Jouppi, Proc. 20th International Symposium on Computer Architecture (ACM Computer Architecture News 21:2), May 1993, pp. 191–201.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;5foot&amp;quot;&amp;gt;[[#5body|5.]]&amp;lt;/span&amp;gt; Architecture of Parallel Computers, Lecture slides by Prof. Edward Gehringer &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;6foot&amp;quot;&amp;gt;[[#6body|6.]]&amp;lt;/span&amp;gt; “Parallel computer architecture: a hardware/software approach” by David. E. Culler, Jaswinder Pal Singh, Anoop Gupta  (pg 887)    &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;7foot&amp;quot;&amp;gt;[[#7body|7.]]&amp;lt;/span&amp;gt; “Evaluating Stream Buffers as a Secondary Cache Replacement” by Subbarao Palacharla and R. E. Kessler.   (ref#2) &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;8foot&amp;quot;&amp;gt;[[#8body|8.]]&amp;lt;/span&amp;gt; http://en.wikipedia.org/wiki/Instruction_prefetch &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;9foot&amp;quot;&amp;gt;[[#9body|9.]]&amp;lt;/span&amp;gt; http://www.real-knowledge.com/memory.htm  &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| border='1' class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|+style=&amp;quot;white-space:nowrap&amp;quot;| Processor Architecture&lt;br /&gt;
|-&lt;br /&gt;
! Company &amp;amp; Processor !! # cores !! L1 cache Per core !! L1 cache Per core !! L3 cache  !! Year&lt;br /&gt;
|-&lt;br /&gt;
| Intel Pentium Dual Core || 2 || I:32KB   D:32KB || 1MB 8 way set assoc.  || -  ||  2006&lt;br /&gt;
|-&lt;br /&gt;
| Intel Xeon Clovertown || 2 || I:4*32KB   D:4*32KB || 2*4MB || - || Jan 2007&lt;br /&gt;
|-&lt;br /&gt;
| Intel Xeon 3200 series || 4 || - || 2*4MB || - || Jan 2007&lt;br /&gt;
|-&lt;br /&gt;
| AMD Athlon 64FX || 2 || I:64KB   D:4KB  Both 2-way set assoc. || 1MB 16way set assoc. || - || Jan 2007&lt;br /&gt;
|-&lt;br /&gt;
| AMD Athlon 64X2 || 2 || I:64KB   D:4KB  Both 2-way set assoc. || 512KB/1MB 16way set assoc. || 2MB || Jan 2007&lt;br /&gt;
|-&lt;br /&gt;
| AMD Barcelona || 4 || I:64KB   D:64KB  || 512KB || 2MB Shared || Aug 2007&lt;br /&gt;
|-&lt;br /&gt;
| Sun Microsystems Ultra Sparc T2 || 8 ||  I:16KB   D:8KB || 4MB (8 banks) 16way set assoc. || - || Oct 2007&lt;br /&gt;
|-&lt;br /&gt;
| Intel Xeon Wolfdale DP || 2 ||  D:96KB  || 6MB || - || Nov 2007&lt;br /&gt;
|-&lt;br /&gt;
| Intel Xeon Hapertown || 4 ||  D:96KB  || 2*6MB || - || Nov 2007&lt;br /&gt;
|-&lt;br /&gt;
| AMD Phenom || 4 || I:64KB   D:64KB  || 512KB || 2MB Shared || Nov 2007    Mar 2008&lt;br /&gt;
|-&lt;br /&gt;
| Intel Core 2 Duo || 2 ||  I:32KB   D:32KB  || 2/4MB 8 way set assoc. || - ||  2008&lt;br /&gt;
|-&lt;br /&gt;
| Intel Penryn Wolfdale DP || 4 ||  -  || 6-12MB || 6MB || Mar 2008   Aug 2008&lt;br /&gt;
|-&lt;br /&gt;
| Intel Core 2 Quad Yorkfield || 4 ||  D:96KB  || 12MB  || - ||  Mar 2008&lt;br /&gt;
|-&lt;br /&gt;
| AMD Toliman || 3K10 || I:64KB   D:64KB  || 512KB || 2MB Shared || Apr 2008&lt;br /&gt;
|-&lt;br /&gt;
| Azul Systems Vega3 7300 Series || 864 || 768GB  || - || - || May 2008&lt;br /&gt;
|-&lt;br /&gt;
| IBM RoadRunner || 8+1 || 32KB  || 512KB || - || Jun 2008&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Pmpatel</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_506_Spring_2011/ch6a_jp&amp;diff=43856</id>
		<title>CSC/ECE 506 Spring 2011/ch6a jp</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_506_Spring_2011/ch6a_jp&amp;diff=43856"/>
		<updated>2011-02-27T00:43:07Z</updated>

		<summary type="html">&lt;p&gt;Pmpatel: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Cache Hierarchy=&lt;br /&gt;
[[Image: memchart.jpg|thumbnail|right|Memory Hierarchy&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;9body&amp;quot;&amp;gt;[[#9foot|[9]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;]]&lt;br /&gt;
In a simple computer model, processor reads data and instructions from the memory and operates on the data.  Operating frequency of CPU increased faster than the speed of memory and memory interconnects.  For example, cores in Intel first generation i7 processors run at 3.2 GHz frequency, while the memory only runs at 1.3GHz frequency.  Also, multi-core architecture started putting more demand on memory bandwidth.  This increases the latency in memory access and CPU will have to be idle for most of the time.  Due to this, memory became a bottle neck in performance.   &lt;br /&gt;
&lt;br /&gt;
To solve this problem, “cache” was invented.  Cache is simply a temporary volatile storage space like primary memory but runs at the speed similar to core frequency.  CPU can access data and instructions from cache in few clock cycles while accessing data from main memory can take more than 50 cycles.  In early days of computing, cache was implemented as a stand alone chip outside the processor.  In today’s processors, cache is implemented on same die as core.  &lt;br /&gt;
&lt;br /&gt;
There can be multiple levels of caches, each cache subsequently away from the core and larger in size.  L1 is closest to the CPU and as a result, fastest to excess.  Next to L1 is L2 cache and then L3.  L1 cache is divided into instruction cache and data cache. This is better than having a combined larger cache as instruction cache being read-only is easy to implement while data cache is read-write.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Cache Write Policies=&lt;br /&gt;
&lt;br /&gt;
==Write hit policies==&lt;br /&gt;
*Write-through: Also known as store-through, this policy will write to main memory whenever a write is performed to cache.&lt;br /&gt;
*Write-back: Also known as store-in or copy-back, this policy will write to main memory only when a block of data is purged from the cache storage.&lt;br /&gt;
&lt;br /&gt;
==Write miss policies==&lt;br /&gt;
*Write-allocate vs Write no-allocate: When a write misses in the cache, there may or may not be a line in the cache allocated to the block.  For write-allocate, there will be a line in the cache for the written data.  This policy is typically associated with write-back caches.  For no-write-allocate, there will not be a line in the cache.&lt;br /&gt;
*Fetch-on-write vs no-fetch-on-write: The fetch-on-write will cause the block of data to be fetched from a lower memory hierarchy if the write misses.  The policy fetches a block on every write miss.  &lt;br /&gt;
*Write-before-hit vs no-write-before-hit:  The write-before-hit will write data to the cache before checking the cache tags for a match.  In case of a miss, the policy will displace the block of data already in the cache.&lt;br /&gt;
&lt;br /&gt;
==Combination Policies==&lt;br /&gt;
* Write-validate: It is a combination of no-fetch-on-write and write-allocate&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;4body&amp;quot;&amp;gt;[[#4foot|[4]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.  The policy allows partial lines to be written to the cache on a miss.  It provides for better performance as well as works with machines that have various line sizes and does not add instruction execution overhead to the program being run.  Write-validate requires that the lower level system memory can support writes of partial lines.&lt;br /&gt;
* Write-invalidate: This policy is a combination of write-before-hit, no-fetch-on-write, and no-write-allocate&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;4body&amp;quot;&amp;gt;[[#4foot|[4]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.  This policy invalidates lines when there is a miss.&lt;br /&gt;
* Write-around:  Combination of no-fetch-on-write, no-write-allocate, and no-write-before-hit&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;4body&amp;quot;&amp;gt;[[#4foot|[4]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.  This policy uses a non-blocking write scheme to write to cache.  It writes data to the next lower cache without modifying the data of the cache line.&lt;br /&gt;
&lt;br /&gt;
=Prefetching=&lt;br /&gt;
Cache is very efficient in terms on access time once that data or instructions are in the cache.  But when a process tries to access something that is not already in the cache, a cache miss occurs and those pages need to be brought into the cache from memory.  Generally cache miss are expensive to the performance as the processor has to wait for that data (In parallel processing, a process can execute other tasks while it is waiting on data, but there will be some overhead for this).  Prefetching is a technique in which data is brought into cache before the program needs it.  In other words, it is a way to reduce cache misses.  Prefetching uses some type of prediction to mechanism to anticipate the next data that will be needed and brings them into cache.  It is not guaranteed that the perfected data will be used.  Goal here is to reduce cache misses to improve overall performance.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Some architectures have instructions to prefetch data into cache.  Programmers and compliers can insert this prefect instruction in the code.  This is known as software prefetching.  In hardware prefetching, processor observers the system behavior and issues requests for prefetching.  Intel 8086 and Motorola 68000 were the first microprocessors to implement instruction prefetch.   Graphics Processing Units benefit from prefetching due to spatial locality property of the data&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;8body&amp;quot;&amp;gt;[[#8foot|[8]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.   &lt;br /&gt;
&lt;br /&gt;
==Advantages==&lt;br /&gt;
*Improves overall performance by reducing cache misses.&lt;br /&gt;
==Disadvantages==&lt;br /&gt;
* Wastes bandwidth when prefetched data is not used.&lt;br /&gt;
* Hardware prefetching requires complex architecture.  Second order effect is cost of implementation on silicon and validation costs.&lt;br /&gt;
* Software prefetching adds additional instructions to the program, making the program larger.&lt;br /&gt;
* If same cache is used for prefetching, then prefetching could cause other cache blocks to be evicted.  If the evicted blocks are needed, then that will generate a cache miss.  This can be prevented by having a separate cache for prefetching but it comes with hardware costs.&lt;br /&gt;
* When scheduler changes the task running on a processor, prefetched data may become useless.&lt;br /&gt;
&lt;br /&gt;
==Effectiveness==&lt;br /&gt;
Prefetching effectiveness can be tracked by following matrices&lt;br /&gt;
# Coverage is defined as fraction of original cache misses that were prefetched resulting in cache hit.&lt;br /&gt;
# Accuracy is defined as fraction of prefetches that are useful.&lt;br /&gt;
# Timeliness measures how early the prefetches arrive.&lt;br /&gt;
Ideally, a system should have high coverage, high accuracy and optimum timeliness.  Realistically, aggressive prefetches can increase coverage but decrease accuracy and vice versa.  Also, if prefetching is done too early, the fetched data may have to be evicted without being used and if done too late, it can cause cache miss.&lt;br /&gt;
&lt;br /&gt;
==Stream Buffer Prefetching==&lt;br /&gt;
This is a technique for prefetching which uses a FIFO buffer in which each entry is a cacheline and has address (or tag) and a available bit.  System prefetches a stream of sequential data into a stream buffer and multiple stream buffers can be used to prefetch multiple streams in parallel.  On a cache access, head entries of stream buffers are check for match along with cache check. If the block is not found in cache but found at the head of stream buffer, it is moved to cache and next entry in the buffer becomes the head.  If the block is not found in cache or as head of buffer, data is brought from memory into cache and the subsequent address as assigned to a new stream buffer.   Only the heads of the stream buffers are checked during cache access and not the whole buffer.  Checking all the entries in all the buffers will increase hardware complexity.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 INSERT IMAGE HERE&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Above plot shows the cache hit improvements for with respect to number of stream buffers on different programs.  Graph on left compares 8 programs from NAS suite while graph on right shows programs from Unix unity suite&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;7body&amp;quot;&amp;gt;[[#7foot|[7]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.  &lt;br /&gt;
==Prefetching in Parallel Computing==&lt;br /&gt;
On a uniprocessor system, prefetching is definitely helpful to improve performance.  On a multiprocessor system prefetching is useful, but there are tighter constrains in implementing because of the fact that data will be shared between different processors or cores.  In message passing parallel model, each parallel thread has its own memory space and prefetching can be implemented in same way as for uniprocessor system.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
In shared memory parallel programming, multiple threads that run on different processors share common memory space.  If multiple processors use common cache, then prefetching implementation is similar to uniprocessor system.  Difficulties arise when each core has its own cache.  Some of the case-scenarios that can occur are:&lt;br /&gt;
# Processor P1 has prefetched some data D1 into its stream buffer but is not used it.  At the same time processor P2 reads data D1 into its cache and modifies it and one of the cache coherency protocols would be used to inform processor P1 about this change.  D1 is not in P1’s cache so it many simply ignore this.  Now, when P1 ties to read D1, it will get the stale data from its stream buffer.  One way to prevent this is by improving stream buffers so that they can modify their data just like a cache.  This adds complexity to the architecture and increases cost&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;6body&amp;quot;&amp;gt;[[#6foot|[6]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
# Prefetching mechanism can fetch data D1, D2, D3,….D10 into P1’s buffer.  Now due to parallel processing, P1 only needs to operate on D1 to D5 while P2 will operate on remaining data.  Some bandwidth was wasted in fetching D6 to D10 into P1 even though it did not use it.  There is a trade off to be made here, if prefetching is very conservative then it will lead to miss and if not then it will waste bandwidth.&lt;br /&gt;
# In a multiprocessor system, if threads are not bound to a core, Operation system can rebalance the treads of different cores.  This will require the prefetched buffers to be trashed.&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
&amp;lt;span id=&amp;quot;1foot&amp;quot;&amp;gt;[[#1body|1.]]&amp;lt;/span&amp;gt; http://www.real-knowledge.com/memory.htm  &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;2foot&amp;quot;&amp;gt;[[#2body|2.]]&amp;lt;/span&amp;gt; Computer Design &amp;amp; Technology- Lectures slides by Prof.Eric Rotenberg  &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;3foot&amp;quot;&amp;gt;[[#3body|3.]]&amp;lt;/span&amp;gt; Fundamentals of Parallel Computer Architecture by Prof.Yan Solihin  &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;4foot&amp;quot;&amp;gt;[[#4body|4.]]&amp;lt;/span&amp;gt; “Cache write policies and performance,” Norman Jouppi, Proc. 20th International Symposium on Computer Architecture (ACM Computer Architecture News 21:2), May 1993, pp. 191–201.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;5foot&amp;quot;&amp;gt;[[#5body|5.]]&amp;lt;/span&amp;gt; Architecture of Parallel Computers, Lecture slides by Prof. Edward Gehringer &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;6foot&amp;quot;&amp;gt;[[#6body|6.]]&amp;lt;/span&amp;gt; “Parallel computer architecture: a hardware/software approach” by David. E. Culler, Jaswinder Pal Singh, Anoop Gupta  (pg 887)    &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;7foot&amp;quot;&amp;gt;[[#7body|7.]]&amp;lt;/span&amp;gt; “Evaluating Stream Buffers as a Secondary Cache Replacement” by Subbarao Palacharla and R. E. Kessler.   (ref#2) &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;8foot&amp;quot;&amp;gt;[[#8body|8.]]&amp;lt;/span&amp;gt; http://en.wikipedia.org/wiki/Instruction_prefetch &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;9foot&amp;quot;&amp;gt;[[#9body|9.]]&amp;lt;/span&amp;gt; http://www.real-knowledge.com/memory.htm  &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| border='1' class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|+style=&amp;quot;white-space:nowrap&amp;quot;| Processor Architecture&lt;br /&gt;
|-&lt;br /&gt;
! Company &amp;amp; Processor !! # cores !! L1 cache Per core !! L1 cache Per core !! L3 cache  !! Year&lt;br /&gt;
|-&lt;br /&gt;
| Intel Pentium Dual Core || 2 || I:32KB   D:32KB || 1MB 8 way set assoc.  || -  ||  2006&lt;br /&gt;
|-&lt;br /&gt;
| Intel Xeon Clovertown || 2 || I:4*32KB   D:4*32KB || 2*4MB || - || Jan 2007&lt;br /&gt;
|-&lt;br /&gt;
| Intel Xeon 3200 series || 4 || - || 2*4MB || - || Jan 2007&lt;br /&gt;
|-&lt;br /&gt;
| AMD Athlon 64FX || 2 || I:64KB   D:4KB  Both 2-way set assoc. || 1MB 16way set assoc. || - || Jan 2007&lt;br /&gt;
|-&lt;br /&gt;
| AMD Athlon 64X2 || 2 || I:64KB   D:4KB  Both 2-way set assoc. || 512KB/1MB 16way set assoc. || 2MB || Jan 2007&lt;br /&gt;
|-&lt;br /&gt;
| AMD Barcelona || 4 || I:64KB   D:64KB  || 512KB || 2MB Shared || Aug 2007&lt;br /&gt;
|-&lt;br /&gt;
| Sun Microsystems Ultra Sparc T2 || 8 || D:8KB   I:16KB  || 4MB (8 banks) 16way set assoc. || - || Oct 2007&lt;br /&gt;
|-&lt;br /&gt;
| Intel Xeon Wolfdale DP || 2 ||  D:96KB  || 6MB || - || Nov 2007&lt;br /&gt;
|-&lt;br /&gt;
| Intel Xeon Hapertown || 4 ||  D:96KB  || 2*6MB || - || Nov 2007&lt;br /&gt;
|-&lt;br /&gt;
| AMD Phenom || 4 || I64KB   D:64KB  || 512KB || 2MB Shared || Nov 2007    Mar 2008&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Pmpatel</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_506_Spring_2011/ch6a_jp&amp;diff=43855</id>
		<title>CSC/ECE 506 Spring 2011/ch6a jp</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_506_Spring_2011/ch6a_jp&amp;diff=43855"/>
		<updated>2011-02-27T00:35:14Z</updated>

		<summary type="html">&lt;p&gt;Pmpatel: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Cache Hierarchy=&lt;br /&gt;
[[Image: memchart.jpg|thumbnail|right|Memory Hierarchy&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;9body&amp;quot;&amp;gt;[[#9foot|[9]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;]]&lt;br /&gt;
In a simple computer model, processor reads data and instructions from the memory and operates on the data.  Operating frequency of CPU increased faster than the speed of memory and memory interconnects.  For example, cores in Intel first generation i7 processors run at 3.2 GHz frequency, while the memory only runs at 1.3GHz frequency.  Also, multi-core architecture started putting more demand on memory bandwidth.  This increases the latency in memory access and CPU will have to be idle for most of the time.  Due to this, memory became a bottle neck in performance.   &lt;br /&gt;
&lt;br /&gt;
To solve this problem, “cache” was invented.  Cache is simply a temporary volatile storage space like primary memory but runs at the speed similar to core frequency.  CPU can access data and instructions from cache in few clock cycles while accessing data from main memory can take more than 50 cycles.  In early days of computing, cache was implemented as a stand alone chip outside the processor.  In today’s processors, cache is implemented on same die as core.  &lt;br /&gt;
&lt;br /&gt;
There can be multiple levels of caches, each cache subsequently away from the core and larger in size.  L1 is closest to the CPU and as a result, fastest to excess.  Next to L1 is L2 cache and then L3.  L1 cache is divided into instruction cache and data cache. This is better than having a combined larger cache as instruction cache being read-only is easy to implement while data cache is read-write.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Cache Write Policies=&lt;br /&gt;
&lt;br /&gt;
==Write hit policies==&lt;br /&gt;
*Write-through: Also known as store-through, this policy will write to main memory whenever a write is performed to cache.&lt;br /&gt;
*Write-back: Also known as store-in or copy-back, this policy will write to main memory only when a block of data is purged from the cache storage.&lt;br /&gt;
&lt;br /&gt;
==Write miss policies==&lt;br /&gt;
*Write-allocate vs Write no-allocate: When a write misses in the cache, there may or may not be a line in the cache allocated to the block.  For write-allocate, there will be a line in the cache for the written data.  This policy is typically associated with write-back caches.  For no-write-allocate, there will not be a line in the cache.&lt;br /&gt;
*Fetch-on-write vs no-fetch-on-write: The fetch-on-write will cause the block of data to be fetched from a lower memory hierarchy if the write misses.  The policy fetches a block on every write miss.  &lt;br /&gt;
*Write-before-hit vs no-write-before-hit:  The write-before-hit will write data to the cache before checking the cache tags for a match.  In case of a miss, the policy will displace the block of data already in the cache.&lt;br /&gt;
&lt;br /&gt;
==Combination Policies==&lt;br /&gt;
* Write-validate: It is a combination of no-fetch-on-write and write-allocate&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;4body&amp;quot;&amp;gt;[[#4foot|[4]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.  The policy allows partial lines to be written to the cache on a miss.  It provides for better performance as well as works with machines that have various line sizes and does not add instruction execution overhead to the program being run.  Write-validate requires that the lower level system memory can support writes of partial lines.&lt;br /&gt;
* Write-invalidate: This policy is a combination of write-before-hit, no-fetch-on-write, and no-write-allocate&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;4body&amp;quot;&amp;gt;[[#4foot|[4]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.  This policy invalidates lines when there is a miss.&lt;br /&gt;
* Write-around:  Combination of no-fetch-on-write, no-write-allocate, and no-write-before-hit&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;4body&amp;quot;&amp;gt;[[#4foot|[4]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.  This policy uses a non-blocking write scheme to write to cache.  It writes data to the next lower cache without modifying the data of the cache line.&lt;br /&gt;
&lt;br /&gt;
=Prefetching=&lt;br /&gt;
Cache is very efficient in terms on access time once that data or instructions are in the cache.  But when a process tries to access something that is not already in the cache, a cache miss occurs and those pages need to be brought into the cache from memory.  Generally cache miss are expensive to the performance as the processor has to wait for that data (In parallel processing, a process can execute other tasks while it is waiting on data, but there will be some overhead for this).  Prefetching is a technique in which data is brought into cache before the program needs it.  In other words, it is a way to reduce cache misses.  Prefetching uses some type of prediction to mechanism to anticipate the next data that will be needed and brings them into cache.  It is not guaranteed that the perfected data will be used.  Goal here is to reduce cache misses to improve overall performance.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Some architectures have instructions to prefetch data into cache.  Programmers and compliers can insert this prefect instruction in the code.  This is known as software prefetching.  In hardware prefetching, processor observers the system behavior and issues requests for prefetching.  Intel 8086 and Motorola 68000 were the first microprocessors to implement instruction prefetch.   Graphics Processing Units benefit from prefetching due to spatial locality property of the data&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;8body&amp;quot;&amp;gt;[[#8foot|[8]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.   &lt;br /&gt;
&lt;br /&gt;
==Advantages==&lt;br /&gt;
*Improves overall performance by reducing cache misses.&lt;br /&gt;
==Disadvantages==&lt;br /&gt;
* Wastes bandwidth when prefetched data is not used.&lt;br /&gt;
* Hardware prefetching requires complex architecture.  Second order effect is cost of implementation on silicon and validation costs.&lt;br /&gt;
* Software prefetching adds additional instructions to the program, making the program larger.&lt;br /&gt;
* If same cache is used for prefetching, then prefetching could cause other cache blocks to be evicted.  If the evicted blocks are needed, then that will generate a cache miss.  This can be prevented by having a separate cache for prefetching but it comes with hardware costs.&lt;br /&gt;
* When scheduler changes the task running on a processor, prefetched data may become useless.&lt;br /&gt;
&lt;br /&gt;
==Effectiveness==&lt;br /&gt;
Prefetching effectiveness can be tracked by following matrices&lt;br /&gt;
# Coverage is defined as fraction of original cache misses that were prefetched resulting in cache hit.&lt;br /&gt;
# Accuracy is defined as fraction of prefetches that are useful.&lt;br /&gt;
# Timeliness measures how early the prefetches arrive.&lt;br /&gt;
Ideally, a system should have high coverage, high accuracy and optimum timeliness.  Realistically, aggressive prefetches can increase coverage but decrease accuracy and vice versa.  Also, if prefetching is done too early, the fetched data may have to be evicted without being used and if done too late, it can cause cache miss.&lt;br /&gt;
&lt;br /&gt;
==Stream Buffer Prefetching==&lt;br /&gt;
This is a technique for prefetching which uses a FIFO buffer in which each entry is a cacheline and has address (or tag) and a available bit.  System prefetches a stream of sequential data into a stream buffer and multiple stream buffers can be used to prefetch multiple streams in parallel.  On a cache access, head entries of stream buffers are check for match along with cache check. If the block is not found in cache but found at the head of stream buffer, it is moved to cache and next entry in the buffer becomes the head.  If the block is not found in cache or as head of buffer, data is brought from memory into cache and the subsequent address as assigned to a new stream buffer.   Only the heads of the stream buffers are checked during cache access and not the whole buffer.  Checking all the entries in all the buffers will increase hardware complexity.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 INSERT IMAGE HERE&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Above plot shows the cache hit improvements for with respect to number of stream buffers on different programs.  Graph on left compares 8 programs from NAS suite while graph on right shows programs from Unix unity suite&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;7body&amp;quot;&amp;gt;[[#7foot|[7]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.  &lt;br /&gt;
==Prefetching in Parallel Computing==&lt;br /&gt;
On a uniprocessor system, prefetching is definitely helpful to improve performance.  On a multiprocessor system prefetching is useful, but there are tighter constrains in implementing because of the fact that data will be shared between different processors or cores.  In message passing parallel model, each parallel thread has its own memory space and prefetching can be implemented in same way as for uniprocessor system.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
In shared memory parallel programming, multiple threads that run on different processors share common memory space.  If multiple processors use common cache, then prefetching implementation is similar to uniprocessor system.  Difficulties arise when each core has its own cache.  Some of the case-scenarios that can occur are:&lt;br /&gt;
# Processor P1 has prefetched some data D1 into its stream buffer but is not used it.  At the same time processor P2 reads data D1 into its cache and modifies it and one of the cache coherency protocols would be used to inform processor P1 about this change.  D1 is not in P1’s cache so it many simply ignore this.  Now, when P1 ties to read D1, it will get the stale data from its stream buffer.  One way to prevent this is by improving stream buffers so that they can modify their data just like a cache.  This adds complexity to the architecture and increases cost&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;6body&amp;quot;&amp;gt;[[#6foot|[6]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
# Prefetching mechanism can fetch data D1, D2, D3,….D10 into P1’s buffer.  Now due to parallel processing, P1 only needs to operate on D1 to D5 while P2 will operate on remaining data.  Some bandwidth was wasted in fetching D6 to D10 into P1 even though it did not use it.  There is a trade off to be made here, if prefetching is very conservative then it will lead to miss and if not then it will waste bandwidth.&lt;br /&gt;
# In a multiprocessor system, if threads are not bound to a core, Operation system can rebalance the treads of different cores.  This will require the prefetched buffers to be trashed.&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
&amp;lt;span id=&amp;quot;1foot&amp;quot;&amp;gt;[[#1body|1.]]&amp;lt;/span&amp;gt; http://www.real-knowledge.com/memory.htm  &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;2foot&amp;quot;&amp;gt;[[#2body|2.]]&amp;lt;/span&amp;gt; Computer Design &amp;amp; Technology- Lectures slides by Prof.Eric Rotenberg  &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;3foot&amp;quot;&amp;gt;[[#3body|3.]]&amp;lt;/span&amp;gt; Fundamentals of Parallel Computer Architecture by Prof.Yan Solihin  &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;4foot&amp;quot;&amp;gt;[[#4body|4.]]&amp;lt;/span&amp;gt; “Cache write policies and performance,” Norman Jouppi, Proc. 20th International Symposium on Computer Architecture (ACM Computer Architecture News 21:2), May 1993, pp. 191–201.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;5foot&amp;quot;&amp;gt;[[#5body|5.]]&amp;lt;/span&amp;gt; Architecture of Parallel Computers, Lecture slides by Prof. Edward Gehringer &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;6foot&amp;quot;&amp;gt;[[#6body|6.]]&amp;lt;/span&amp;gt; “Parallel computer architecture: a hardware/software approach” by David. E. Culler, Jaswinder Pal Singh, Anoop Gupta  (pg 887)    &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;7foot&amp;quot;&amp;gt;[[#7body|7.]]&amp;lt;/span&amp;gt; “Evaluating Stream Buffers as a Secondary Cache Replacement” by Subbarao Palacharla and R. E. Kessler.   (ref#2) &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;8foot&amp;quot;&amp;gt;[[#8body|8.]]&amp;lt;/span&amp;gt; http://en.wikipedia.org/wiki/Instruction_prefetch &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;9foot&amp;quot;&amp;gt;[[#9body|9.]]&amp;lt;/span&amp;gt; http://www.real-knowledge.com/memory.htm  &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| border='1' class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|+style=&amp;quot;white-space:nowrap&amp;quot;| Processor Architecture&lt;br /&gt;
|-&lt;br /&gt;
! Company &amp;amp; Processor !! # cores !! L1 cache Per core !! L1 cache Per core !! L3 cache  !! Year&lt;br /&gt;
|-&lt;br /&gt;
| Intel Pentium Dual Core || 2 || I:32KB   D:32KB || 1MB 8 way set assoc.  || -  ||  2006&lt;br /&gt;
|-&lt;br /&gt;
| Intel Xeon Clovertown || 2 || I:4*32KB   D:4*32KB || 2*4MB || - || Jan 2007&lt;br /&gt;
|-&lt;br /&gt;
| Intel Xeon 3200 series || 4 || - || 2*4MB || - || Jan 2007&lt;br /&gt;
|-&lt;br /&gt;
| AMD Athlon 64FX || 2 || I:4*32KB   D:4KB  Both 2-way set assoc. || 1MB 16way set assoc. || - || Jan 2007&lt;br /&gt;
|-&lt;br /&gt;
| AMD Athlon 64FX || 2 || I:4*32KB   D:4KB  Both 2-way set assoc. || 1MB 16way set assoc. || - || Jan 2007&lt;br /&gt;
|-&lt;br /&gt;
| AMD Athlon 64FX || 2 || I:4*32KB   D:4KB  Both 2-way set assoc. || 1MB 16way set assoc. || - || Jan 2007&lt;br /&gt;
|-&lt;br /&gt;
| AMD Athlon 64FX || 2 || I:4*32KB   D:4KB  Both 2-way set assoc. || 1MB 16way set assoc. || - || Jan 2007&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Pmpatel</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_506_Spring_2011/ch6a_jp&amp;diff=43854</id>
		<title>CSC/ECE 506 Spring 2011/ch6a jp</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_506_Spring_2011/ch6a_jp&amp;diff=43854"/>
		<updated>2011-02-27T00:29:59Z</updated>

		<summary type="html">&lt;p&gt;Pmpatel: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Cache Hierarchy=&lt;br /&gt;
[[Image: memchart.jpg|thumbnail|right|Memory Hierarchy&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;9body&amp;quot;&amp;gt;[[#9foot|[9]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;]]&lt;br /&gt;
In a simple computer model, processor reads data and instructions from the memory and operates on the data.  Operating frequency of CPU increased faster than the speed of memory and memory interconnects.  For example, cores in Intel first generation i7 processors run at 3.2 GHz frequency, while the memory only runs at 1.3GHz frequency.  Also, multi-core architecture started putting more demand on memory bandwidth.  This increases the latency in memory access and CPU will have to be idle for most of the time.  Due to this, memory became a bottle neck in performance.   &lt;br /&gt;
&lt;br /&gt;
To solve this problem, “cache” was invented.  Cache is simply a temporary volatile storage space like primary memory but runs at the speed similar to core frequency.  CPU can access data and instructions from cache in few clock cycles while accessing data from main memory can take more than 50 cycles.  In early days of computing, cache was implemented as a stand alone chip outside the processor.  In today’s processors, cache is implemented on same die as core.  &lt;br /&gt;
&lt;br /&gt;
There can be multiple levels of caches, each cache subsequently away from the core and larger in size.  L1 is closest to the CPU and as a result, fastest to excess.  Next to L1 is L2 cache and then L3.  L1 cache is divided into instruction cache and data cache. This is better than having a combined larger cache as instruction cache being read-only is easy to implement while data cache is read-write.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Cache Write Policies=&lt;br /&gt;
&lt;br /&gt;
==Write hit policies==&lt;br /&gt;
*Write-through: Also known as store-through, this policy will write to main memory whenever a write is performed to cache.&lt;br /&gt;
*Write-back: Also known as store-in or copy-back, this policy will write to main memory only when a block of data is purged from the cache storage.&lt;br /&gt;
&lt;br /&gt;
==Write miss policies==&lt;br /&gt;
*Write-allocate vs Write no-allocate: When a write misses in the cache, there may or may not be a line in the cache allocated to the block.  For write-allocate, there will be a line in the cache for the written data.  This policy is typically associated with write-back caches.  For no-write-allocate, there will not be a line in the cache.&lt;br /&gt;
*Fetch-on-write vs no-fetch-on-write: The fetch-on-write will cause the block of data to be fetched from a lower memory hierarchy if the write misses.  The policy fetches a block on every write miss.  &lt;br /&gt;
*Write-before-hit vs no-write-before-hit:  The write-before-hit will write data to the cache before checking the cache tags for a match.  In case of a miss, the policy will displace the block of data already in the cache.&lt;br /&gt;
&lt;br /&gt;
==Combination Policies==&lt;br /&gt;
* Write-validate: It is a combination of no-fetch-on-write and write-allocate&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;4body&amp;quot;&amp;gt;[[#4foot|[4]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.  The policy allows partial lines to be written to the cache on a miss.  It provides for better performance as well as works with machines that have various line sizes and does not add instruction execution overhead to the program being run.  Write-validate requires that the lower level system memory can support writes of partial lines.&lt;br /&gt;
* Write-invalidate: This policy is a combination of write-before-hit, no-fetch-on-write, and no-write-allocate&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;4body&amp;quot;&amp;gt;[[#4foot|[4]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.  This policy invalidates lines when there is a miss.&lt;br /&gt;
* Write-around:  Combination of no-fetch-on-write, no-write-allocate, and no-write-before-hit&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;4body&amp;quot;&amp;gt;[[#4foot|[4]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.  This policy uses a non-blocking write scheme to write to cache.  It writes data to the next lower cache without modifying the data of the cache line.&lt;br /&gt;
&lt;br /&gt;
=Prefetching=&lt;br /&gt;
Cache is very efficient in terms on access time once that data or instructions are in the cache.  But when a process tries to access something that is not already in the cache, a cache miss occurs and those pages need to be brought into the cache from memory.  Generally cache miss are expensive to the performance as the processor has to wait for that data (In parallel processing, a process can execute other tasks while it is waiting on data, but there will be some overhead for this).  Prefetching is a technique in which data is brought into cache before the program needs it.  In other words, it is a way to reduce cache misses.  Prefetching uses some type of prediction to mechanism to anticipate the next data that will be needed and brings them into cache.  It is not guaranteed that the perfected data will be used.  Goal here is to reduce cache misses to improve overall performance.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Some architectures have instructions to prefetch data into cache.  Programmers and compliers can insert this prefect instruction in the code.  This is known as software prefetching.  In hardware prefetching, processor observers the system behavior and issues requests for prefetching.  Intel 8086 and Motorola 68000 were the first microprocessors to implement instruction prefetch.   Graphics Processing Units benefit from prefetching due to spatial locality property of the data&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;8body&amp;quot;&amp;gt;[[#8foot|[8]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.   &lt;br /&gt;
&lt;br /&gt;
==Advantages==&lt;br /&gt;
*Improves overall performance by reducing cache misses.&lt;br /&gt;
==Disadvantages==&lt;br /&gt;
* Wastes bandwidth when prefetched data is not used.&lt;br /&gt;
* Hardware prefetching requires complex architecture.  Second order effect is cost of implementation on silicon and validation costs.&lt;br /&gt;
* Software prefetching adds additional instructions to the program, making the program larger.&lt;br /&gt;
* If same cache is used for prefetching, then prefetching could cause other cache blocks to be evicted.  If the evicted blocks are needed, then that will generate a cache miss.  This can be prevented by having a separate cache for prefetching but it comes with hardware costs.&lt;br /&gt;
* When scheduler changes the task running on a processor, prefetched data may become useless.&lt;br /&gt;
&lt;br /&gt;
==Effectiveness==&lt;br /&gt;
Prefetching effectiveness can be tracked by following matrices&lt;br /&gt;
# Coverage is defined as fraction of original cache misses that were prefetched resulting in cache hit.&lt;br /&gt;
# Accuracy is defined as fraction of prefetches that are useful.&lt;br /&gt;
# Timeliness measures how early the prefetches arrive.&lt;br /&gt;
Ideally, a system should have high coverage, high accuracy and optimum timeliness.  Realistically, aggressive prefetches can increase coverage but decrease accuracy and vice versa.  Also, if prefetching is done too early, the fetched data may have to be evicted without being used and if done too late, it can cause cache miss.&lt;br /&gt;
&lt;br /&gt;
==Stream Buffer Prefetching==&lt;br /&gt;
This is a technique for prefetching which uses a FIFO buffer in which each entry is a cacheline and has address (or tag) and a available bit.  System prefetches a stream of sequential data into a stream buffer and multiple stream buffers can be used to prefetch multiple streams in parallel.  On a cache access, head entries of stream buffers are check for match along with cache check. If the block is not found in cache but found at the head of stream buffer, it is moved to cache and next entry in the buffer becomes the head.  If the block is not found in cache or as head of buffer, data is brought from memory into cache and the subsequent address as assigned to a new stream buffer.   Only the heads of the stream buffers are checked during cache access and not the whole buffer.  Checking all the entries in all the buffers will increase hardware complexity.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 INSERT IMAGE HERE&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Above plot shows the cache hit improvements for with respect to number of stream buffers on different programs.  Graph on left compares 8 programs from NAS suite while graph on right shows programs from Unix unity suite&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;7body&amp;quot;&amp;gt;[[#7foot|[7]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.  &lt;br /&gt;
==Prefetching in Parallel Computing==&lt;br /&gt;
On a uniprocessor system, prefetching is definitely helpful to improve performance.  On a multiprocessor system prefetching is useful, but there are tighter constrains in implementing because of the fact that data will be shared between different processors or cores.  In message passing parallel model, each parallel thread has its own memory space and prefetching can be implemented in same way as for uniprocessor system.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
In shared memory parallel programming, multiple threads that run on different processors share common memory space.  If multiple processors use common cache, then prefetching implementation is similar to uniprocessor system.  Difficulties arise when each core has its own cache.  Some of the case-scenarios that can occur are:&lt;br /&gt;
# Processor P1 has prefetched some data D1 into its stream buffer but is not used it.  At the same time processor P2 reads data D1 into its cache and modifies it and one of the cache coherency protocols would be used to inform processor P1 about this change.  D1 is not in P1’s cache so it many simply ignore this.  Now, when P1 ties to read D1, it will get the stale data from its stream buffer.  One way to prevent this is by improving stream buffers so that they can modify their data just like a cache.  This adds complexity to the architecture and increases cost&amp;lt;sup&amp;gt;&amp;lt;span id=&amp;quot;6body&amp;quot;&amp;gt;[[#6foot|[6]]]&amp;lt;/span&amp;gt;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
# Prefetching mechanism can fetch data D1, D2, D3,….D10 into P1’s buffer.  Now due to parallel processing, P1 only needs to operate on D1 to D5 while P2 will operate on remaining data.  Some bandwidth was wasted in fetching D6 to D10 into P1 even though it did not use it.  There is a trade off to be made here, if prefetching is very conservative then it will lead to miss and if not then it will waste bandwidth.&lt;br /&gt;
# In a multiprocessor system, if threads are not bound to a core, Operation system can rebalance the treads of different cores.  This will require the prefetched buffers to be trashed.&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
&amp;lt;span id=&amp;quot;1foot&amp;quot;&amp;gt;[[#1body|1.]]&amp;lt;/span&amp;gt; http://www.real-knowledge.com/memory.htm  &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;2foot&amp;quot;&amp;gt;[[#2body|2.]]&amp;lt;/span&amp;gt; Computer Design &amp;amp; Technology- Lectures slides by Prof.Eric Rotenberg  &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;3foot&amp;quot;&amp;gt;[[#3body|3.]]&amp;lt;/span&amp;gt; Fundamentals of Parallel Computer Architecture by Prof.Yan Solihin  &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;4foot&amp;quot;&amp;gt;[[#4body|4.]]&amp;lt;/span&amp;gt; “Cache write policies and performance,” Norman Jouppi, Proc. 20th International Symposium on Computer Architecture (ACM Computer Architecture News 21:2), May 1993, pp. 191–201.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;5foot&amp;quot;&amp;gt;[[#5body|5.]]&amp;lt;/span&amp;gt; Architecture of Parallel Computers, Lecture slides by Prof. Edward Gehringer &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;6foot&amp;quot;&amp;gt;[[#6body|6.]]&amp;lt;/span&amp;gt; “Parallel computer architecture: a hardware/software approach” by David. E. Culler, Jaswinder Pal Singh, Anoop Gupta  (pg 887)    &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;7foot&amp;quot;&amp;gt;[[#7body|7.]]&amp;lt;/span&amp;gt; “Evaluating Stream Buffers as a Secondary Cache Replacement” by Subbarao Palacharla and R. E. Kessler.   (ref#2) &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;8foot&amp;quot;&amp;gt;[[#8body|8.]]&amp;lt;/span&amp;gt; http://en.wikipedia.org/wiki/Instruction_prefetch &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;9foot&amp;quot;&amp;gt;[[#9body|9.]]&amp;lt;/span&amp;gt; http://www.real-knowledge.com/memory.htm  &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| border='1' class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|+style=&amp;quot;white-space:nowrap&amp;quot;| Processor Architecture&lt;br /&gt;
|-&lt;br /&gt;
! Company &amp;amp; Processor !! # cores !! L1 cache Per core !! L1 cache Per core !! L3 cache  !! Year&lt;br /&gt;
|-&lt;br /&gt;
| Intel Pentium Dual Core || 2 || I:32KB   D:32KB || 1MB 8 way set assoc.  || -  ||  2006&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 2 || 4 || 6&lt;br /&gt;
|-&lt;br /&gt;
| 3 || 3 || 6 || 9&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Pmpatel</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_506_Spring_2011/ch6a_jp&amp;diff=43826</id>
		<title>CSC/ECE 506 Spring 2011/ch6a jp</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_506_Spring_2011/ch6a_jp&amp;diff=43826"/>
		<updated>2011-02-26T23:09:54Z</updated>

		<summary type="html">&lt;p&gt;Pmpatel: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Cache Hierarchy=&lt;br /&gt;
In a simple computer model, processor reads data and instructions from the memory and operates on the data.  Operating frequency of CPU increased faster than the speed of memory and memory interconnects.  For example, cores in Intel first generation i7 processors run at 3.2 GHz frequency, while the memory only runs at 1.3GHz frequency.  Also, multi-core architecture started putting more demand on memory bandwidth.  This increases the latency in memory access and CPU will have to be idle for most of the time.  Due to this, memory became a bottle neck in performance.   &lt;br /&gt;
&lt;br /&gt;
To solve this problem, “cache” was invented.  Cache is simply a temporary volatile storage space like primary memory but runs at the speed similar to core frequency.  CPU can access data and instructions from cache in few clock cycles while accessing data from main memory can take more than 50 cycles.  In early days of computing, cache was implemented as a stand alone chip outside the processor.  In today’s processors, cache is implemented on same die as core.  &lt;br /&gt;
&lt;br /&gt;
There can be multiple levels of caches, each cache subsequently away from the core and larger in size.  L1 is closest to the CPU and as a result, fastest to excess.  Next to L1 is L2 cache and then L3.  L1 cache is divided into instruction cache and data cache. This is better than having a combined larger cache as instruction cache being read-only is easy to implement while data cache is read-write.&lt;br /&gt;
&lt;br /&gt;
=Cache Write Policies=&lt;br /&gt;
&lt;br /&gt;
==Write hit policies==&lt;br /&gt;
===Write-through===&lt;br /&gt;
Also known as store-through, this policy will write to main memory whenever a write is performed to cache.&lt;br /&gt;
===Write-back===&lt;br /&gt;
Also known as store-in or copy-back, this policy will write to main memory only when a block of data is purged from the cache storage.&lt;br /&gt;
&lt;br /&gt;
==Write miss policies==&lt;br /&gt;
===Write-allocate vs Write no-allocate===&lt;br /&gt;
When a write misses in the cache, there may or may not be a line in the cache allocated to the block.  For write-allocate, there will be a line in the cache for the written data.  This policy is typically associated with write-back caches.  For no-write-allocate, there will not be a line in the cache.&lt;br /&gt;
===Fetch-on-write vs no-fetch-on-write===&lt;br /&gt;
The fetch-on-write will cause the block of data to be fetched from a lower memory hierarchy if the write misses.  The policy fetches a block on every write miss.  &lt;br /&gt;
===Write-before-hit vs no-write-before-hit===&lt;br /&gt;
The write-before-hit will write data to the cache before checking the cache tags for a match.  In case of a miss, the policy will displace the block of data already in the cache.&lt;br /&gt;
&lt;br /&gt;
==Combination Policies==&lt;br /&gt;
===Write-validate===&lt;br /&gt;
It is a combination of no-fetch-on-write and write-allocate.  The policy allows partial lines to be written to the cache on a miss.  It provides for better performance as well as works with machines that have various line sizes and does not add instruction execution overhead to the program being run.&lt;br /&gt;
===Write-invalidate===&lt;br /&gt;
This policy is a combination of write-before-hit, no-fetch-on-write, and no-write-allocate.  This policy invalidates lines when there is a miss.&lt;br /&gt;
===Write-around===&lt;br /&gt;
Combination of no-fetch-on-write, no-write-allocate, and no-write-before-hit.  This policy uses a non-blocking write scheme to write to cache.  It writes data to the next lower cache without modifying the data of the cache line.&lt;br /&gt;
&lt;br /&gt;
=Prefetching=&lt;br /&gt;
&lt;br /&gt;
==Advantages==&lt;br /&gt;
&lt;br /&gt;
==Disadvantages==&lt;br /&gt;
&lt;br /&gt;
==Effectiveness==&lt;br /&gt;
&lt;br /&gt;
==Stream Buffer Prefetching==&lt;br /&gt;
&lt;br /&gt;
==Prefetching in Parallel Computing==&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Header 1&lt;br /&gt;
! Header 2&lt;br /&gt;
! Header 3&lt;br /&gt;
|-&lt;br /&gt;
| row 1, cell 1&lt;br /&gt;
| row 1, cell 2&lt;br /&gt;
| row 1, cell 3&lt;br /&gt;
|-&lt;br /&gt;
| row 2, cell 1&lt;br /&gt;
| row 2, cell 2&lt;br /&gt;
| row 2, cell 3&lt;br /&gt;
|-&lt;br /&gt;
| row 3, cell 1&lt;br /&gt;
| row 3, cell 2&lt;br /&gt;
| row 3, cell 3&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| border='1' class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|+style=&amp;quot;white-space:nowrap&amp;quot;| Multiplication table&lt;br /&gt;
|-&lt;br /&gt;
! &amp;amp;times; !! 1 !! 2 !! 3&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1 || 2 || 3&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 2 || 4 || 6&lt;br /&gt;
|-&lt;br /&gt;
| 3 || 3 || 6 || 9&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Pmpatel</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_506_Spring_2011/ch6a_jp&amp;diff=43822</id>
		<title>CSC/ECE 506 Spring 2011/ch6a jp</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_506_Spring_2011/ch6a_jp&amp;diff=43822"/>
		<updated>2011-02-26T22:55:34Z</updated>

		<summary type="html">&lt;p&gt;Pmpatel: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Bold text'''&amp;lt;nowiki&amp;gt;Insert non-formatted text here&amp;lt;/nowiki&amp;gt;--[[User:Pmpatel|Pmpatel]] 17:55, 26 February 2011 (EST)[[Media:Example.ogg]]&amp;lt;math&amp;gt;Insert formula here&amp;lt;/math&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
Test&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Header 1&lt;br /&gt;
! Header 2&lt;br /&gt;
! Header 3&lt;br /&gt;
|-&lt;br /&gt;
| row 1, cell 1&lt;br /&gt;
| row 1, cell 2&lt;br /&gt;
| row 1, cell 3&lt;br /&gt;
|-&lt;br /&gt;
| row 2, cell 1&lt;br /&gt;
| row 2, cell 2&lt;br /&gt;
| row 2, cell 3&lt;br /&gt;
|-&lt;br /&gt;
| row 3, cell 1&lt;br /&gt;
| row 3, cell 2&lt;br /&gt;
| row 3, cell 3&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|+style=&amp;quot;white-space:nowrap&amp;quot;| Multiplication table&lt;br /&gt;
|-&lt;br /&gt;
! &amp;amp;times; !! 1 !! 2 !! 3&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1 || 2 || 3&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 2 || 4 || 6&lt;br /&gt;
|-&lt;br /&gt;
| 3 || 3 || 6 || 9&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Pmpatel</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_506_Spring_2011/ch6a_jp&amp;diff=43821</id>
		<title>CSC/ECE 506 Spring 2011/ch6a jp</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_506_Spring_2011/ch6a_jp&amp;diff=43821"/>
		<updated>2011-02-26T22:49:52Z</updated>

		<summary type="html">&lt;p&gt;Pmpatel: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Test&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Header 1&lt;br /&gt;
! Header 2&lt;br /&gt;
! Header 3&lt;br /&gt;
|-&lt;br /&gt;
| row 1, cell 1&lt;br /&gt;
| row 1, cell 2&lt;br /&gt;
| row 1, cell 3&lt;br /&gt;
|-&lt;br /&gt;
| row 2, cell 1&lt;br /&gt;
| row 2, cell 2&lt;br /&gt;
| row 2, cell 3&lt;br /&gt;
|-&lt;br /&gt;
| row 3, cell 1&lt;br /&gt;
| row 3, cell 2&lt;br /&gt;
| row 3, cell 3&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|+style=&amp;quot;white-space:nowrap&amp;quot;| Multiplication table&lt;br /&gt;
|-&lt;br /&gt;
! &amp;amp;times; !! 1 !! 2 !! 3&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1 || 2 || 3&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 2 || 4 || 6&lt;br /&gt;
|-&lt;br /&gt;
| 3 || 3 || 6 || 9&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Pmpatel</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_506_Spring_2011/ch6a_jp&amp;diff=43820</id>
		<title>CSC/ECE 506 Spring 2011/ch6a jp</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_506_Spring_2011/ch6a_jp&amp;diff=43820"/>
		<updated>2011-02-26T22:18:53Z</updated>

		<summary type="html">&lt;p&gt;Pmpatel: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Test&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Header 1&lt;br /&gt;
! Header 2&lt;br /&gt;
! Header 3&lt;br /&gt;
|-&lt;br /&gt;
| row 1, cell 1&lt;br /&gt;
| row 1, cell 2&lt;br /&gt;
| row 1, cell 3&lt;br /&gt;
|-&lt;br /&gt;
| row 2, cell 1&lt;br /&gt;
| row 2, cell 2&lt;br /&gt;
| row 2, cell 3&lt;br /&gt;
|-&lt;br /&gt;
| row 3, cell 1&lt;br /&gt;
| row 3, cell 2&lt;br /&gt;
| row 3, cell 3&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Pmpatel</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_506_Spring_2011/ch6a_jp&amp;diff=43819</id>
		<title>CSC/ECE 506 Spring 2011/ch6a jp</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_506_Spring_2011/ch6a_jp&amp;diff=43819"/>
		<updated>2011-02-26T22:16:08Z</updated>

		<summary type="html">&lt;p&gt;Pmpatel: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Test&lt;br /&gt;
&lt;br /&gt;
| p1 |  p2  | p3  |&lt;br /&gt;
|    |      |     |&lt;/div&gt;</summary>
		<author><name>Pmpatel</name></author>
	</entry>
</feed>