<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: OpenMP vs Windows APIs in Intel® Moderncode for Parallel Architectures</title>
    <link>https://community.intel.com/t5/Intel-Moderncode-for-Parallel/OpenMP-vs-Windows-APIs/m-p/884682#M3467</link>
    <description>&lt;DIV style="margin:0px;"&gt;&lt;/DIV&gt;&lt;P&gt;Thank you very much for your help! It has been sooo useful!&lt;/P&gt;&lt;P&gt;Michele&lt;/P&gt;</description>
    <pubDate>Mon, 29 Sep 2008 16:34:23 GMT</pubDate>
    <dc:creator>michele86</dc:creator>
    <dc:date>2008-09-29T16:34:23Z</dc:date>
    <item>
      <title>OpenMP vs Windows APIs</title>
      <link>https://community.intel.com/t5/Intel-Moderncode-for-Parallel/OpenMP-vs-Windows-APIs/m-p/884678#M3463</link>
      <description>Hi everybody! I'm doing a comparison between OpenMP and Windows API performances over two versions of the same "producer - consumer" problem: there are n producers, m consumers and a shared buffer (an int array) of NUM positions. I'm doing the test with an Intel Core Duo and Windows Vista Home Premium. I've downloaded the Intel C++ Compiler (evaluation version), and I use it by prompt. Well, when I run programs specifying only one producer and one consumer the OpenMp version is more efficient, in the other hand when I specify a number of threads &amp;gt;2 OpenMP's performances fly down like an hungry eagle, while WinAPI's ones are still good. I've also tried to run both versions at the same time, observing that the WinAPI version used more than 80% of the CPU, producing over 10 times data compared to the OpenMP one. To sincronyze threads within the WinAPI version I use critical sections and condition variables , while I use #pragma omp critical (...) and #pragma omp flush (...) within the OpenMP one.&lt;BR /&gt;&lt;BR /&gt;Can anybody explain to me the causes of those differences?&lt;BR /&gt;How does OpenMP create threads at runtime? &lt;BR /&gt;Why does they have less priority than Windows brothers?&lt;BR /&gt;&lt;BR /&gt;Thank you very much!&lt;BR /&gt;Michele.&lt;BR /&gt;</description>
      <pubDate>Wed, 17 Sep 2008 18:50:14 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Moderncode-for-Parallel/OpenMP-vs-Windows-APIs/m-p/884678#M3463</guid>
      <dc:creator>michele86</dc:creator>
      <dc:date>2008-09-17T18:50:14Z</dc:date>
    </item>
    <item>
      <title>Re: OpenMP vs Windows APIs</title>
      <link>https://community.intel.com/t5/Intel-Moderncode-for-Parallel/OpenMP-vs-Windows-APIs/m-p/884679#M3464</link>
      <description>&lt;P&gt;Michele,&lt;/P&gt;
&lt;P&gt;Could you post your test programs (both versions)?&lt;/P&gt;
&lt;P&gt;Jim Dempsey&lt;/P&gt;
&lt;P&gt;&lt;/P&gt;</description>
      <pubDate>Thu, 18 Sep 2008 18:13:04 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Moderncode-for-Parallel/OpenMP-vs-Windows-APIs/m-p/884679#M3464</guid>
      <dc:creator>jimdempseyatthecove</dc:creator>
      <dc:date>2008-09-18T18:13:04Z</dc:date>
    </item>
    <item>
      <title>Re: OpenMP vs Windows APIs</title>
      <link>https://community.intel.com/t5/Intel-Moderncode-for-Parallel/OpenMP-vs-Windows-APIs/m-p/884680#M3465</link>
      <description>I think performances go down because of the high number of flush
operations, but an OpenMP.org developer told me that this is the only
way to avoid race-conditions (is it correct?).&lt;BR /&gt;I tried to find a way to achieve an exclusive access to the shared variable within while-conditions, but I didn't succeed. &lt;BR /&gt;Thank you very much for your help!&lt;BR /&gt;&lt;BR /&gt;&lt;FONT color="#ff0000"&gt;OpenMP version:&lt;/FONT&gt;&lt;BR /&gt;
&lt;BR /&gt;
#include &lt;STDIO.H&gt;&lt;BR /&gt;#include &lt;WINDOWS.H&gt;&lt;BR /&gt;#include &lt;TIME.H&gt;&lt;BR /&gt;#include &lt;OMP.H&gt;&lt;BR /&gt;#define NUM 10   //buffer size&lt;BR /&gt;#define TIME 3000&lt;BR /&gt;&lt;BR /&gt;int main(int argc, char *argv[]){&lt;BR /&gt;&lt;BR /&gt; int buffer[NUM]; &lt;BR /&gt; int start;  //index of the first element a consumer has to consume&lt;BR /&gt; int end;  //index of the first free position in the buffer&lt;BR /&gt; unsigned long PTemp; //the new element the producer has to insert in the buffer&lt;BR /&gt; unsigned long CTemp;&lt;BR /&gt; int full,empty;&lt;BR /&gt; int dataNum;  //number of data in the buffer&lt;BR /&gt; unsigned long dataCNum;  //number of data consumed&lt;BR /&gt; int np,nc,finished;&lt;BR /&gt; double time_start,time_end;&lt;BR /&gt;&lt;BR /&gt; CTemp=PTemp=dataCNum=0;&lt;BR /&gt; start=end=full=dataNum=np=nc=finished=0;&lt;BR /&gt; empty=1;&lt;BR /&gt; &lt;BR /&gt; if(argc!=3){&lt;BR /&gt;  printf("You have to specify the number of producers and the number of consumers!

");&lt;BR /&gt;  return 1;&lt;BR /&gt; }&lt;BR /&gt;&lt;BR /&gt; np=atoi(argv[1]); //number of producers&lt;BR /&gt; nc=atoi(argv[2]); //number of consumers&lt;BR /&gt;&lt;BR /&gt; omp_set_nested(2);&lt;BR /&gt;&lt;BR /&gt; time_start=clock();&lt;BR /&gt;&lt;BR /&gt; #pragma omp parallel sections num_threads(3)&lt;BR /&gt; {&lt;BR /&gt; #pragma omp section   //producer's code&lt;BR /&gt; {&lt;BR /&gt; #pragma omp parallel num_threads(np)&lt;BR /&gt; while(!finished){&lt;BR /&gt;  #pragma omp flush(full,finished)&lt;BR /&gt;  while(full&amp;amp;&amp;amp;!finished){&lt;BR /&gt;   #pragma omp critical (control)&lt;BR /&gt;   {&lt;BR /&gt;    #pragma omp flush(dataNum)&lt;BR /&gt;    if(dataNum&lt;NUM&gt;     full=0;&lt;BR /&gt;    }&lt;BR /&gt;    #pragma omp flush(full,finished)&lt;BR /&gt;   }&lt;BR /&gt;  }&lt;BR /&gt;  #pragma omp critical (control)&lt;BR /&gt;  {&lt;BR /&gt;  #pragma omp flush(finished)&lt;BR /&gt;  if(!finished){&lt;BR /&gt;  #pragma omp flush(dataNum)&lt;BR /&gt;  if(dataNum&lt;NUM&gt;   #pragma omp flush(PTemp)&lt;BR /&gt;   PTemp++;&lt;BR /&gt;   #pragma omp flush(PTemp,end)&lt;BR /&gt;   buffer[end]=PTemp;&lt;BR /&gt;   #pragma omp flush(dataNum)&lt;BR /&gt;   dataNum++;&lt;BR /&gt;   #pragma omp flush(dataNum)&lt;BR /&gt;   //printf("PRODUCER %d: produced data = %d (dataNum = %d)

",omp_get_thread_num(),PTemp,dataNum);&lt;BR /&gt;   #pragma omp flush(end)&lt;BR /&gt;   end=(end+1)%NUM;&lt;BR /&gt;   #pragma omp flush(end)&lt;BR /&gt;  }&lt;BR /&gt;  else{&lt;BR /&gt;   full=1;&lt;BR /&gt;   #pragma omp flush(full)&lt;BR /&gt;  }&lt;BR /&gt;  }//if !finished&lt;BR /&gt;  #pragma omp flush(finished)&lt;BR /&gt;  }//critical control&lt;BR /&gt; }//while&lt;BR /&gt; }//section&lt;BR /&gt; #pragma omp section   //consumer's code&lt;BR /&gt; {&lt;BR /&gt; #pragma omp parallel num_threads(nc) private(CTemp)&lt;BR /&gt; while(!finished||dataNum&amp;gt;0){&lt;BR /&gt;  #pragma omp flush(empty,finished)&lt;BR /&gt;  while(empty&amp;amp;&amp;amp;!finished){&lt;BR /&gt;   #pragma omp critical (control)&lt;BR /&gt;   {&lt;BR /&gt;    #pragma omp flush(dataNum)&lt;BR /&gt;    if(dataNum&amp;gt;0){&lt;BR /&gt;     empty=0;&lt;BR /&gt;     #pragma omp flush(empty,finished)&lt;BR /&gt;    }&lt;BR /&gt;   }&lt;BR /&gt;  }&lt;BR /&gt;  #pragma omp critical (control)&lt;BR /&gt;  {&lt;BR /&gt;  #pragma omp flush(dataNum)&lt;BR /&gt;  if(dataNum&amp;gt;0){&lt;BR /&gt;   #pragma omp flush(start)&lt;BR /&gt;   CTemp=buffer[start];&lt;BR /&gt;   #pragma omp flush(dataNum)&lt;BR /&gt;  &amp;amp;nb
sp; dataNum--;&lt;BR /&gt;   #pragma omp flush(dataNum)&lt;BR /&gt;   //printf("CONSUMER %d: consumed data = %d (dataNum= %d)

",omp_get_thread_num(),CTemp,dataNum);&lt;BR /&gt;   #pragma omp flush(start)&lt;BR /&gt;   start=(start+1)%NUM;&lt;BR /&gt;   #pragma omp flush(start,dataCNum)&lt;BR /&gt;   dataCNum++;&lt;BR /&gt;   #pragma omp flush(dataCNum)&lt;BR /&gt;  }&lt;BR /&gt;  else{&lt;BR /&gt;   empty=1;&lt;BR /&gt;   #pragma omp flush(empty)&lt;BR /&gt;  }&lt;BR /&gt;  #pragma omp flush(finished)&lt;BR /&gt;  }//critical control&lt;BR /&gt; }//while&lt;BR /&gt; }//section&lt;BR /&gt; #pragma omp section&lt;BR /&gt; {&lt;BR /&gt;  Sleep(TIME);&lt;BR /&gt;  //printf("Tempo scaduto!!

");&lt;BR /&gt;  #pragma omp critical (control)&lt;BR /&gt;  {&lt;BR /&gt;   finished=1;&lt;BR /&gt;   #pragma omp flush(finished)&lt;BR /&gt;  }&lt;BR /&gt; }//section&lt;BR /&gt; }//sections&lt;BR /&gt; time_end=clock();&lt;BR /&gt; printf("Time = %.0f millisec - data produced= %u , data consumed= %u

",time_end-time_start,PTemp,dataCNum);&lt;BR /&gt; return 0;&lt;BR /&gt;}&lt;BR /&gt;&lt;FONT color="#ff0000"&gt;&lt;BR /&gt;&lt;BR /&gt;WinAPI version:&lt;/FONT&gt;&lt;BR /&gt;&lt;BR /&gt;#include &lt;WINDOWS.H&gt;&lt;BR /&gt;#include &lt;PROCESS.H&gt;&lt;BR /&gt;#include &lt;STDIO.H&gt;&lt;BR /&gt;#include &lt;TIME.H&gt;&lt;BR /&gt;#define NUM 10&lt;BR /&gt;#define TIME 3000&lt;BR /&gt;#define NP 10&lt;BR /&gt;#define NC 10&lt;BR /&gt;&lt;BR /&gt;int buffer[NUM];&lt;BR /&gt;int start,end,dataNum,PTemp,stop;&lt;BR /&gt;unsigned long dataCNum,dataPNum;&lt;BR /&gt;CRITICAL_SECTION CritSect;&lt;BR /&gt;CONDITION_VARIABLE full,empty;&lt;BR /&gt;&lt;BR /&gt;DWORD WINAPI start_producer(PVOID p){&lt;BR /&gt; ULONG Pid=(ULONG)(ULONG_PTR)p;&lt;BR /&gt; while(1){&lt;BR /&gt; EnterCriticalSection(&amp;amp;CritSect);&lt;BR /&gt; while(dataNum&amp;gt;=NUM &amp;amp;&amp;amp; !stop){&lt;BR /&gt;  SleepConditionVariableCS(&amp;amp;full,&amp;amp;CritSect,INFINITE);&lt;BR /&gt; }&lt;BR /&gt; if(stop){&lt;BR /&gt; LeaveCriticalSection(&amp;amp;CritSect);&lt;BR /&gt; break;&lt;BR /&gt; }&lt;BR /&gt; PTemp++;&lt;BR /&gt; buffer[end]=PTemp;&lt;BR /&gt; dataNum++;&lt;BR /&gt; //printf("***Producer %d : produced datum = %d, dataNum = %d

",Pid,PTemp,dataNum);&lt;BR /&gt; end=(end+1)%NUM;&lt;BR /&gt; dataPNum++;&lt;BR /&gt; LeaveCriticalSection(&amp;amp;CritSect);&lt;BR /&gt; WakeConditionVariable(∅);&lt;BR /&gt; }&lt;BR /&gt;&amp;nbsp;
; //printf("***Producer %d : finished!!

",Pid);&lt;BR /&gt; return 0;&lt;BR /&gt;}&lt;BR /&gt;&lt;BR /&gt;DWORD WINAPI start_consumer(PVOID p){&lt;BR /&gt; int CTemp;&lt;BR /&gt; ULONG Cid=(ULONG)(ULONG_PTR)p;&lt;BR /&gt; while(1){&lt;BR /&gt; EnterCriticalSection(&amp;amp;CritSect);&lt;BR /&gt; while(dataNum&amp;lt;=0 &amp;amp;&amp;amp; !stop){&lt;BR /&gt; SleepConditionVariableCS(∅,&amp;amp;CritSect,INFINITE);&lt;BR /&gt; }&lt;BR /&gt; if(stop &amp;amp;&amp;amp; dataNum&amp;lt;=0){&lt;BR /&gt; LeaveCriticalSection(&amp;amp;CritSect);&lt;BR /&gt; break;&lt;BR /&gt; }&lt;BR /&gt; CTemp=buffer[start];&lt;BR /&gt; dataNum--;&lt;BR /&gt; //printf("Consumer %d : consumed datum = %d, dataNum = %d

",Cid,CTemp,dataNum);&lt;BR /&gt; start=(start+1)%NUM;&lt;BR /&gt; dataCNum++;&lt;BR /&gt; LeaveCriticalSection(&amp;amp;CritSect);&lt;BR /&gt; WakeConditionVariable(&amp;amp;full);&lt;BR /&gt; //Sleep (rand() % CONSUMER_SLEEP_TIME_MS);&lt;BR /&gt; }&lt;BR /&gt; //printf("Consumer %d : finished!!

",Cid);&lt;BR /&gt; return 0;&lt;BR /&gt;}&lt;BR /&gt;&lt;BR /&gt;&lt;BR /&gt;int main(int argc, char *argv[]){&lt;BR /&gt;&lt;BR /&gt; HANDLE producers[NP], consumers[NC];&lt;BR /&gt; double time_start,time_end;&lt;BR /&gt; start=end=dataNum=PTemp=stop=dataCNum=dataPNum=0;&lt;BR /&gt;&lt;BR /&gt; InitializeConditionVariable(&amp;amp;full);&lt;BR /&gt; InitializeConditionVariable(∅);&lt;BR /&gt; InitializeCriticalSection(&amp;amp;CritSect);&lt;BR /&gt;&lt;BR /&gt; DWORD id;&lt;BR /&gt; EnterCriticalSection(&amp;amp;CritSect);&lt;BR /&gt; for(int i=0;i&lt;NP&gt;  producers&lt;I&gt;=CreateThread(NULL, 0, start_producer, (PVOID)i, 0, &amp;amp;id);&lt;BR /&gt; }&lt;BR /&gt; for(int i=0;i&lt;NC&gt;  consumers&lt;I&gt;=CreateThread(NULL, 0, start_consumer, (PVOID)i, 0, &amp;amp;id);&lt;BR /&gt; }&lt;BR /&gt; LeaveCriticalSection(&amp;amp;CritSect);&lt;BR /&gt;&lt;BR /&gt; time_start=clock();&lt;BR /&gt; Sleep(TIME);&lt;BR /&gt; EnterCriticalSection(&amp;amp;CritSect);&lt;BR /&gt; stop=1;&lt;BR /&gt; LeaveCriticalSection(&amp;amp;CritSect);&lt;BR /&gt;&lt;BR /&gt; WakeAllConditionVariable(&amp;amp;full);&lt;BR /&gt; WakeAllConditionVariable(∅);&lt;BR /&gt;&lt;BR /&gt; for(int i=0;i&lt;NP&gt;  WaitForSingleObject(producers&lt;I&gt;,INFINITE);&lt;BR /&gt; }&lt;BR /&gt; for(int i=0;i&lt;NC&gt;  WaitForSingleObject(consumers&lt;I&gt;,INFINITE);&lt;BR /&gt; }&lt;BR /&gt; time_end=clock();&lt;BR /&gt; printf("Time = %.0f millisec - data produced = %u - data consumed = %u

",time_end-time_start,dataPNum,dataCNum);&lt;BR /&gt; return 0;&lt;BR /&gt;}&lt;BR /&gt;&lt;/I&gt;&lt;/NC&gt;&lt;/I&gt;&lt;/NP&gt;&lt;/I&gt;&lt;/NC&gt;&lt;/I&gt;&lt;/NP&gt;&lt;/TIME.H&gt;&lt;/STDIO.H&gt;&lt;/PROCESS.H&gt;&lt;/WINDOWS.H&gt;&lt;/NUM&gt;&lt;/NUM&gt;&lt;/OMP.H&gt;&lt;/TIME.H&gt;&lt;/WINDOWS.H&gt;&lt;/STDIO.H&gt;</description>
      <pubDate>Thu, 18 Sep 2008 21:23:47 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Moderncode-for-Parallel/OpenMP-vs-Windows-APIs/m-p/884680#M3465</guid>
      <dc:creator>michele86</dc:creator>
      <dc:date>2008-09-18T21:23:47Z</dc:date>
    </item>
    <item>
      <title>Re: OpenMP vs Windows APIs</title>
      <link>https://community.intel.com/t5/Intel-Moderncode-for-Parallel/OpenMP-vs-Windows-APIs/m-p/884681#M3466</link>
      <description>&lt;DIV id="quote_reply" style="margin-top: 5px; width: 100%;"&gt;&lt;BR /&gt;
&lt;DIV style="margin-left:2px;margin-right:2px;"&gt;Quoting - &lt;A href="https://community.intel.com/en-us/profile/332886"&gt;michele86&lt;/A&gt;&lt;/DIV&gt;&lt;BR /&gt;
&lt;DIV style="background-color:#E5E5E5; padding:5px;border: 1px; border-style: inset;margin-left:2px;margin-right:2px;"&gt;&lt;EM&gt;I think performances go down because of the high number of flush operations, but an OpenMP.org developer told me that this is the only way to avoid race-conditions (is it correct?).&lt;BR /&gt;
I tried to find a way to achieve an exclusive access to the shared variable within while-conditions, but I didn't succeed.&lt;BR /&gt;
Thank you very much for your help!&lt;BR /&gt;
&lt;BR /&gt;
&lt;SPAN style="color: #ff0000;"&gt;OpenMP version:&lt;/SPAN&gt;&lt;BR /&gt;
&lt;BR /&gt;
#include &lt;STDIO.H&gt;&lt;BR /&gt;
#include &lt;WINDOWS.H&gt;&lt;BR /&gt;
#include &lt;TIME.H&gt;&lt;BR /&gt;
#include &lt;OMP.H&gt;&lt;BR /&gt;
#define NUM 10   //buffer size&lt;BR /&gt;
#define TIME 3000&lt;BR /&gt;
&lt;BR /&gt;
int main(int argc, char *argv[]){&lt;BR /&gt;
&lt;BR /&gt;
 int buffer[NUM];&lt;BR /&gt;
 int start;  //index of the first element a consumer has to consume&lt;BR /&gt;
 int end;  //index of the first free position in the buffer&lt;BR /&gt;
 unsigned long PTemp; //the new element the producer has to insert in the buffer&lt;BR /&gt;
 unsigned long CTemp;&lt;BR /&gt;
 int full,empty;&lt;BR /&gt;
 int dataNum;  //number of data in the buffer&lt;BR /&gt;
 unsigned long dataCNum;  //number of data consumed&lt;BR /&gt;
 int np,nc,finished;&lt;BR /&gt;
 double time_start,time_end;&lt;BR /&gt;
&lt;BR /&gt;
 CTemp=PTemp=dataCNum=0;&lt;BR /&gt;
 start=end=full=dataNum=np=nc=finished=0;&lt;BR /&gt;
 empty=1;&lt;BR /&gt;
&lt;BR /&gt;
 if(argc!=3){&lt;BR /&gt;
  printf("You have to specify the number of producers and the number of consumers! ");&lt;BR /&gt;
  return 1;&lt;BR /&gt;
 }&lt;BR /&gt;
&lt;BR /&gt;
 np=atoi(argv[1]); //number of producers&lt;BR /&gt;
 nc=atoi(argv[2]); //number of consumers&lt;BR /&gt;
&lt;BR /&gt;
 omp_set_nested(2);&lt;BR /&gt;
&lt;BR /&gt;
 time_start=clock();&lt;BR /&gt;
&lt;BR /&gt;
 #pragma omp parallel sections num_threads(3)&lt;BR /&gt;
 {&lt;BR /&gt;
 #pragma omp section   //producer's code&lt;BR /&gt;
 {&lt;BR /&gt;
 #pragma omp parallel num_threads(np)&lt;BR /&gt;
 while(!finished){&lt;BR /&gt;
  #pragma omp flush(full,finished)&lt;BR /&gt;
  while(full&amp;amp;&amp;amp;!finished){&lt;BR /&gt;
   #pragma omp critical (control)&lt;BR /&gt;
   {&lt;BR /&gt;
    #pragma omp flush(dataNum)&lt;BR /&gt;
    if(dataNum&lt;NUM&gt;&lt;/NUM&gt;
     full=0;&lt;BR /&gt;
    }&lt;BR /&gt;
    #pragma omp flush(full,finished)&lt;BR /&gt;
   }&lt;BR /&gt;
  }&lt;BR /&gt;
  #pragma omp critical (control)&lt;BR /&gt;
  {&lt;BR /&gt;
  #pragma omp flush(finished)&lt;BR /&gt;
  if(!finished){&lt;BR /&gt;
  #pragma omp flush(dataNum)&lt;BR /&gt;
  if(dataNum&lt;NUM&gt;&lt;/NUM&gt;
   #pragma omp flush(PTemp)&lt;BR /&gt;
   PTemp++;&lt;BR /&gt;
   #pragma omp flush(PTemp,end)&lt;BR /&gt;
   buffer[end]=PTemp;&lt;BR /&gt;
   #pragma omp flush(dataNum)&lt;BR /&gt;
   dataNum++;&lt;BR /&gt;
   #pragma omp flush(dataNum)&lt;BR /&gt;
   //printf("PRODUCER %d: produced data = %d (dataNum = %d) ",omp_get_thread_num(),PTemp,dataNum);&lt;BR /&gt;
   #pragma omp flush(end)&lt;BR /&gt;
   end=(end+1)%NUM;&lt;BR /&gt;
   #pragma omp flush(end)&lt;BR /&gt;
  }&lt;BR /&gt;
  else{&lt;BR /&gt;
   full=1;&lt;BR /&gt;
   #pragma omp flush(full)&lt;BR /&gt;
  }&lt;BR /&gt;
  }//if !finished&lt;BR /&gt;
  #pragma omp flush(finished)&lt;BR /&gt;
  }//critical control&lt;BR /&gt;
 }//while&lt;BR /&gt;
 }//section&lt;BR /&gt;
 #pragma omp section   //consumer's code&lt;BR /&gt;
 {&lt;BR /&gt;
 #pragma omp parallel num_threads(nc) private(CTemp)&lt;BR /&gt;
 while(!finished||dataNum&amp;gt;0){&lt;BR /&gt;
  #pragma omp flush(empty,finished)&lt;BR /&gt;
  while(empty&amp;amp;&amp;amp;!finished){&lt;BR /&gt;
   #pragma omp critical (control)&lt;BR /&gt;
   {&lt;BR /&gt;
    #pragma omp flush(dataNum)&lt;BR /&gt;
    if(dataNum&amp;gt;0){&lt;BR /&gt;
     empty=0;&lt;BR /&gt;
     #pragma omp flush(empty,finished)&lt;BR /&gt;
    }&lt;BR /&gt;
   }&lt;BR /&gt;
  }&lt;BR /&gt;
  #pragma omp critical (control)&lt;BR /&gt;
  {&lt;BR /&gt;
  #pragma omp flush(dataNum)&lt;BR /&gt;
  if(dataNum&amp;gt;0){&lt;BR /&gt;
   #pragma omp flush(start)&lt;BR /&gt;
   CTemp=buffer[start];&lt;BR /&gt;
   #pragma omp flush(dataNum)&lt;BR /&gt;
  &amp;amp;nb sp; dataNum--;&lt;BR /&gt;
   #pragma omp flush(dataNum)&lt;BR /&gt;
   //printf("CONSUMER %d: consumed data = %d (dataNum= %d) ",omp_get_thread_num(),CTemp,dataNum);&lt;BR /&gt;
   #pragma omp flush(start)&lt;BR /&gt;
   start=(start+1)%NUM;&lt;BR /&gt;
   #pragma omp flush(start,dataCNum)&lt;BR /&gt;
   dataCNum++;&lt;BR /&gt;
   #pragma omp flush(dataCNum)&lt;BR /&gt;
  }&lt;BR /&gt;
  else{&lt;BR /&gt;
   empty=1;&lt;BR /&gt;
   #pragma omp flush(empty)&lt;BR /&gt;
  }&lt;BR /&gt;
  #pragma omp flush(finished)&lt;BR /&gt;
  }//critical control&lt;BR /&gt;
 }//while&lt;BR /&gt;
 }//section&lt;BR /&gt;
 #pragma omp section&lt;BR /&gt;
 {&lt;BR /&gt;
  Sleep(TIME);&lt;BR /&gt;
  //printf("Tempo scaduto!! ");&lt;BR /&gt;
  #pragma omp critical (control)&lt;BR /&gt;
  {&lt;BR /&gt;
   finished=1;&lt;BR /&gt;
   #pragma omp flush(finished)&lt;BR /&gt;
  }&lt;BR /&gt;
 }//section&lt;BR /&gt;
 }//sections&lt;BR /&gt;
 time_end=clock();&lt;BR /&gt;
 printf("Time = %.0f millisec - data produced= %u , data consumed= %u ",time_end-time_start,PTemp,dataCNum);&lt;BR /&gt;
 return 0;&lt;BR /&gt;
}&lt;BR /&gt;
&lt;SPAN style="color: #ff0000;"&gt;&lt;BR /&gt;
&lt;BR /&gt;
WinAPI version:&lt;/SPAN&gt;&lt;BR /&gt;
&lt;BR /&gt;
#include &lt;WINDOWS.H&gt;&lt;BR /&gt;
#include &lt;PROCESS.H&gt;&lt;BR /&gt;
#include &lt;STDIO.H&gt;&lt;BR /&gt;
#include &lt;TIME.H&gt;&lt;BR /&gt;
#define NUM 10&lt;BR /&gt;
#define TIME 3000&lt;BR /&gt;
#define NP 10&lt;BR /&gt;
#define NC 10&lt;BR /&gt;
&lt;BR /&gt;
int buffer[NUM];&lt;BR /&gt;
int start,end,dataNum,PTemp,stop;&lt;BR /&gt;
unsigned long dataCNum,dataPNum;&lt;BR /&gt;
CRITICAL_SECTION CritSect;&lt;BR /&gt;
CONDITION_VARIABLE full,empty;&lt;BR /&gt;
&lt;BR /&gt;
DWORD WINAPI start_producer(PVOID p){&lt;BR /&gt;
 ULONG Pid=(ULONG)(ULONG_PTR)p;&lt;BR /&gt;
 while(1){&lt;BR /&gt;
 EnterCriticalSection(&amp;amp;CritSect);&lt;BR /&gt;
 while(dataNum&amp;gt;=NUM &amp;amp;&amp;amp; !stop){&lt;BR /&gt;
  SleepConditionVariableCS(&amp;amp;full,&amp;amp;CritSect,INFINITE);&lt;BR /&gt;
 }&lt;BR /&gt;
 if(stop){&lt;BR /&gt;
 LeaveCriticalSection(&amp;amp;CritSect);&lt;BR /&gt;
 break;&lt;BR /&gt;
 }&lt;BR /&gt;
 PTemp++;&lt;BR /&gt;
 buffer[end]=PTemp;&lt;BR /&gt;
 dataNum++;&lt;BR /&gt;
 //printf("***Producer %d : produced datum = %d, dataNum = %d ",Pid,PTemp,dataNum);&lt;BR /&gt;
 end=(end+1)%NUM;&lt;BR /&gt;
 dataPNum++;&lt;BR /&gt;
 LeaveCriticalSection(&amp;amp;CritSect);&lt;BR /&gt;
 WakeConditionVariable(∅);&lt;BR /&gt;
 }&lt;BR /&gt;
 ; //printf("***Producer %d : finished!! ",Pid);&lt;BR /&gt;
 return 0;&lt;BR /&gt;
}&lt;BR /&gt;
&lt;BR /&gt;
DWORD WINAPI start_consumer(PVOID p){&lt;BR /&gt;
 int CTemp;&lt;BR /&gt;
 ULONG Cid=(ULONG)(ULONG_PTR)p;&lt;BR /&gt;
 while(1){&lt;BR /&gt;
 EnterCriticalSection(&amp;amp;CritSect);&lt;BR /&gt;
 while(dataNum&amp;lt;=0 &amp;amp;&amp;amp; !stop){&lt;BR /&gt;
 SleepConditionVariableCS(∅,&amp;amp;CritSect,INFINITE);&lt;BR /&gt;
 }&lt;BR /&gt;
 if(stop &amp;amp;&amp;amp; dataNum&amp;lt;=0){&lt;BR /&gt;
 LeaveCriticalSection(&amp;amp;CritSect);&lt;BR /&gt;
 break;&lt;BR /&gt;
 }&lt;BR /&gt;
 CTemp=buffer[start];&lt;BR /&gt;
 dataNum--;&lt;BR /&gt;
 //printf("Consumer %d : consumed datum = %d, dataNum = %d ",Cid,CTemp,dataNum);&lt;BR /&gt;
 start=(start+1)%NUM;&lt;BR /&gt;
 dataCNum++;&lt;BR /&gt;
 LeaveCriticalSection(&amp;amp;CritSect);&lt;BR /&gt;
 WakeConditionVariable(&amp;amp;full);&lt;BR /&gt;
 //Sleep (rand() % CONSUMER_SLEEP_TIME_MS);&lt;BR /&gt;
 }&lt;BR /&gt;
 //printf("Consumer %d : finished!! ",Cid);&lt;BR /&gt;
 return 0;&lt;BR /&gt;
}&lt;BR /&gt;
&lt;BR /&gt;
int main(int argc, char *argv[]){&lt;BR /&gt;
&lt;BR /&gt;
 HANDLE producers[NP], consumers[NC];&lt;BR /&gt;
 double time_start,time_end;&lt;BR /&gt;
 start=end=dataNum=PTemp=stop=dataCNum=dataPNum=0;&lt;BR /&gt;
&lt;BR /&gt;
 InitializeConditionVariable(&amp;amp;full);&lt;BR /&gt;
 InitializeConditionVariable(∅);&lt;BR /&gt;
 InitializeCriticalSection(&amp;amp;CritSect);&lt;BR /&gt;
&lt;BR /&gt;
 DWORD id;&lt;BR /&gt;
 EnterCriticalSection(&amp;amp;CritSect);&lt;BR /&gt;
 for(int i=0;i&lt;NP&gt;&lt;/NP&gt;
  producers&lt;I&gt;=CreateThread(NULL, 0, start_producer, (PVOID)i, 0, &amp;amp;id);&lt;BR /&gt;
 }&lt;BR /&gt;
 for(int i=0;i&lt;NC&gt;&lt;/NC&gt;
  consumers&lt;I&gt;=CreateThread(NULL, 0, start_consumer, (PVOID)i, 0, &amp;amp;id);&lt;BR /&gt;
 }&lt;BR /&gt;
 LeaveCriticalSection(&amp;amp;CritSect);&lt;BR /&gt;
&lt;BR /&gt;
 time_start=clock();&lt;BR /&gt;
 Sleep(TIME);&lt;BR /&gt;
 EnterCriticalSection(&amp;amp;CritSect);&lt;BR /&gt;
 stop=1;&lt;BR /&gt;
 LeaveCriticalSection(&amp;amp;CritSect);&lt;BR /&gt;
&lt;BR /&gt;
 WakeAllConditionVariable(&amp;amp;full);&lt;BR /&gt;
 WakeAllConditionVariable(∅);&lt;BR /&gt;
&lt;BR /&gt;
 for(int i=0;i&lt;NP&gt;&lt;/NP&gt;
  WaitForSingleObject(producers&lt;I&gt;,INFINITE);&lt;BR /&gt;
 }&lt;BR /&gt;
 for(int i=0;i&lt;NC&gt;&lt;/NC&gt;
  WaitForSingleObject(consumers&lt;I&gt;,INFINITE);&lt;BR /&gt;
 }&lt;BR /&gt;
 time_end=clock();&lt;BR /&gt;
 printf("Time = %.0f millisec - data produced = %u - data consumed = %u ",time_end-time_start,dataPNum,dataCNum);&lt;BR /&gt;
 return 0;&lt;BR /&gt;
}&lt;BR /&gt;
&lt;/I&gt;&lt;/I&gt;&lt;/I&gt;&lt;/I&gt;&lt;/TIME.H&gt;&lt;/STDIO.H&gt;&lt;/PROCESS.H&gt;&lt;/WINDOWS.H&gt;&lt;/OMP.H&gt;&lt;/TIME.H&gt;&lt;/WINDOWS.H&gt;&lt;/STDIO.H&gt;&lt;/EM&gt;&lt;I&gt;&lt;I&gt;&lt;I&gt;&lt;I&gt;&lt;/I&gt;&lt;/I&gt;&lt;/I&gt;&lt;/I&gt;&lt;/DIV&gt;&lt;BR /&gt;
&lt;/DIV&gt;&lt;BR /&gt;
Michele,&lt;BR /&gt;
&lt;BR /&gt;
I wish to apologize for taking so long to reply to your post. I had other pressing issues to resolve.&lt;BR /&gt;
&lt;BR /&gt;
Your shared variables should contain "volatile" (Example: volatile int datNum;)&lt;BR /&gt;
The purpose of this is to provide the compiler with the information that the value of the variable may unexpectedly change and therefor the compiler's code optimization should not place the value into a register but instead, obtain a new copy of the variable upon every reference.&lt;BR /&gt;
&lt;BR /&gt;
Entry into and exit from critical sections have an implicit memory barrier (i.e. flushes occure when crossing barrier).&lt;BR /&gt;
Therefor, the flushes to push/pull the values to/from other threads is not required (assuming same named critical section).&lt;BR /&gt;
&lt;BR /&gt;
Consider using a macro to define "full"&lt;BR /&gt;
&lt;BR /&gt;
 #define full (dataNum==NUM)&lt;BR /&gt;
&lt;BR /&gt;
remember to remove the int declaration for full.&lt;BR /&gt;
&lt;BR /&gt;
Rewrite the section that clears full (full is a macro now)&lt;BR /&gt;
&lt;BR /&gt;
 while(!finished){&lt;BR /&gt;
 while(full&amp;amp;&amp;amp;!finished)&lt;BR /&gt;
 SwitchToThread();&lt;BR /&gt;
&lt;BR /&gt;
&lt;BR /&gt;
 #pragma omp critical (control)&lt;BR /&gt;
 {&lt;BR /&gt;
 if(!finished){&lt;BR /&gt;
 if(!full){&lt;BR /&gt;
 PTemp++;&lt;BR /&gt;
 buffer[end]=PTemp;&lt;BR /&gt;
 dataNum++;&lt;BR /&gt;
 //printf("PRODUCER %d: produced data = %d (dataNum = %d) ",omp_get_thread_num(),PTemp,dataNum);&lt;BR /&gt;
 end=(end+1)%NUM;&lt;BR /&gt;
 }&lt;BR /&gt;
 }//if !finished&lt;BR /&gt;
 }//critical control&lt;BR /&gt;
 }//while&lt;BR /&gt;
&lt;BR /&gt;
For short duration waits use _mm_pause();, SwitchToThread();, or Sleep(0);&lt;BR /&gt;
&lt;BR /&gt;
When the number of running threads is =&lt;THE number="" of="" cores="" then="" consider="" using="" _mm_pause=""&gt;&lt;/THE&gt;
When the number of runningtheads is &amp;gt; the number of cores then consider using SwitchToThread(); as it has less overhead than Sleep(0); Sleep(0) will permit threads to migrate from core to core (if that is desireable) whereas SwitchToThread tends to place the running thread at the tail end of threads waiting to run on the core at the time of the call to SwitchToThread.&lt;BR /&gt;
&lt;BR /&gt;
Jim Dempsey</description>
      <pubDate>Thu, 25 Sep 2008 19:08:02 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Moderncode-for-Parallel/OpenMP-vs-Windows-APIs/m-p/884681#M3466</guid>
      <dc:creator>jimdempseyatthecove</dc:creator>
      <dc:date>2008-09-25T19:08:02Z</dc:date>
    </item>
    <item>
      <title>Re: OpenMP vs Windows APIs</title>
      <link>https://community.intel.com/t5/Intel-Moderncode-for-Parallel/OpenMP-vs-Windows-APIs/m-p/884682#M3467</link>
      <description>&lt;DIV style="margin:0px;"&gt;&lt;/DIV&gt;&lt;P&gt;Thank you very much for your help! It has been sooo useful!&lt;/P&gt;&lt;P&gt;Michele&lt;/P&gt;</description>
      <pubDate>Mon, 29 Sep 2008 16:34:23 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Moderncode-for-Parallel/OpenMP-vs-Windows-APIs/m-p/884682#M3467</guid>
      <dc:creator>michele86</dc:creator>
      <dc:date>2008-09-29T16:34:23Z</dc:date>
    </item>
  </channel>
</rss>

