OpenMP


OpenMP

The Open multi-processing is an application programming interface to create parallel programming applications.
El Multi-procesamiento Abierto es una interface de programación de aplicaciones para crear aplicaciones con programación en paralelo.

Problem 1
Create a Wintempla Dialog application called DirectPi to compute the value of π. After creating the application, add a multi-line textbox called tbxOutput.
Cree una aplicación de diálogo llamada DirectPi para calcular el valor de π. Después de crear el programa, agregue una caja de texto de multi-líneas llamada tbxOutput.

DirectPiRun

Step B
Edit the DirectPi.cpp file.
Edite el archivo DirectPi.cpp.

DirectPi.cpp
. . .
void DirectPi::Window_Open(Win::Event& e)
{
     Sys::Stopwatch sw;
     double sum = 0.0;
     const size_t maxIterations = 99999999;
     for (size_t i = 0; i < maxIterations; i++)
     {
          //___________________________________________ 1. Perform calculation
          if (i%2 == 0)
               sum += (1.0/(2*i+1));
          else
               sum -= (1.0/(2*i+1));
     }
     tbxOutput.Text = sw.GetMillisecondsText();
     wchar_t text[32];
     _snwprintf_s(text, 32, _TRUNCATE, L"\r\n%.14f", 4.0*sum);
     tbxOutput.Text += text;
}


Step B
When finish editing the files, change the configuration to Release and run the program.
Cuando termine editando los archivos, cambie la configuración Release y ejecute el programa.

Problem 2
Create a Wintempla Dialog application called CaclPi to compute the value of π using a thread pool. After creating the application, add a multi-line textbox called tbxOutput.
Cree una aplicación de diálogo llamada CaclPi para calcular el valor de π usando un arreglo de threads. Después de crear el programa, agregue una caja de texto de multi-líneas llamada tbxOutput.

CaclPiRun

Step A
Edit the CaclPi.h file. Do not forget to implement the Mt::IThreadX interface.
Edite el archivo CaclPi.h. No sé olvide de implementar la interface Mt::IThreadX.

CaclPi.h
#pragma once //______________________________________ CaclPi.h
#include "Resource.h"
class CaclPi: public Win::Dialog, public Mt::IThreadX
{
public:
     CaclPi()
     {
     }
     ~CaclPi()
     {
     }
     valarray<double> result;
     Mt::ThreadPool pool;
     //____________________________________________________________ IThreadX
     DWORD ThreadFunc(Mt::BoolTs& cancel, size_t threadIndex, size_t numThreads);
protected:
     . . .
};


Step B
Edit the CaclPi.cpp file.
Edite el archivo CaclPi.cpp.

CalcPi.cpp
. . .
void CaclPi::Window_Open(Win::Event& e)
{
     const size_t numThreads = pool.NumThreads;
     result.resize(numThreads);
     Sys::Stopwatch sw;
     pool.BeginAll(*this);
     pool.WaitForAll();
     tbxOutput.Text = sw.GetMillisecondsText();
     wchar_t text[32];
     _snwprintf_s(text, 32, _TRUNCATE, L"\r\n%.14f", 4.0*result.sum());
     tbxOutput.Text += text;
}

DWORD CaclPi::ThreadFunc(Mt::BoolTs& cancel, size_t threadIndex, size_t numThreads)
{
     result[threadIndex] = 0.0;
     const size_t maxIterations = 99999999;
     const size_t first = Mt::WorkDistributionFirst(threadIndex, numThreads, maxIterations);
     const size_t last = Mt::WorkDistributionLast(threadIndex, numThreads, maxIterations);
     for (size_t i = first; i < last; i++)
     {
          //___________________________________________ 1. Perform partial calculation
          if (i%2 == 0)
               result[threadIndex] += (1.0/(2*i+1));
          else
               result[threadIndex] -= (1.0/(2*i+1));
     }
     return 0;
}


Step C
When finish editing the files, change the configuration to Release and run the program.
Cuando termine editando los archivos, cambie la configuración Release y ejecute el programa.

Problem 3
Make a list of the main differences between the programs: DirectPi and CaclPi.
Haga una lista de las diferencias principales entre los programas: DirectPi y CaclPi.

Problem 4
Create a Wintempla Dialog application called Simple to compute the value of π using a thread pool. After creating the application, add a multi-line textbox called tbxOutput.
Cree una aplicación de diálogo llamada Simple para calcular el valor de π usando un arreglo de threads. Después de crear el programa, agregue una caja de texto de multi-líneas llamada tbxOutput.

SimpleRun

Step A
Edit the Simple.h file. Do not forget to implement the Mt::IThreadX interface.
Edite el archivo Simple.h. No sé olvide de implementar la interface Mt::IThreadX.

Simple.h
#pragma once //______________________________________ Simple.h
#include "Resource.h"
class Simple: public Win::Dialog, public Mt::IThreadX
{
public:
     Simple()
     {
     }
     ~Simple()
     {
     }
     Mt::CriticalSection cs;
     double valuePi = 0.0;
     Mt::ThreadPool pool;
     //____________________________________________________________ IThreadX
     DWORD ThreadFunc(Mt::BoolTs& cancel, size_t threadIndex, size_t numThreads);
protected:
     . . .
};


Step B
Edit the Simple.cpp file.
Edite el archivo Simple.cpp.

Simple.cpp
. . .
void Simple::Window_Open(Win::Event& e)
{
     Sys::Stopwatch sw;
     pool.BeginAll(*this);
     pool.WaitForAll();
     tbxOutput.Text = sw.GetMillisecondsText();
     wchar_t text[32];
     _snwprintf_s(text, 32, _TRUNCATE, L"\r\n%.14f", valuePi);
     tbxOutput.Text += text;
}

DWORD Simple::ThreadFunc(Mt::BoolTs& cancel, size_t threadIndex, size_t numThreads)
{
     double sum = 0.0;
     const size_t maxIterations = 99999999;
     const size_t first = Mt::WorkDistributionFirst(threadIndex, numThreads, maxIterations);
     const size_t last = Mt::WorkDistributionLast(threadIndex, numThreads, maxIterations);
     for (size_t i = first; i < last; i++)
     {
          //___________________________________________ 1. Perform partial calculation
          if (i%2 == 0)
               sum += (1.0/(2*i+1));
          else
               sum -= (1.0/(2*i+1));
     }
     //_____________________________________________ 2. Incorporate partial result
     cs.Enter();
     valuePi += 4.0*sum;
     cs.Leave();
     return 0;
}

Step C
When finish editing the files, change the configuration to Release and run the program.
Cuando termine editando los archivos, cambie la configuración Release y ejecute el programa.

Problem 5
Make a list of the main differences between the programs: CaclPi and Simple.
Haga una lista de las diferencias principales entre los programas: CaclPi y Simple.

Problem 6
Create a Wintempla Dialog application called BasicM to test some basic OpenMP functions. using a thread pool. After creating the application, add a multi-line textbox called tbxOutput.
Cree una aplicación de diálogo llamada BasicM para probar algunas funciones básicas de OpenMP. Después de crear el programa, agregue una caja de texto de multi-líneas llamada tbxOutput.

BasicMRun

Step A
Open Solution Explorer, select the project and right click to open the context menu. Then, select Properties to open the project properties dialog. Finally, select "All Configurations" and select the OpenMP switch as shown.
Abra el Solution Explorer, seleccione el proyecto y haga clic con el botón derecho del ratón para abrir el menú de contexto. Entonces seleccione Properties para abrir el diálogo de las propiedades del proyecto. Finalmente, seleccionar "All Configurations" y seleccione OpenMP como se muestra.

Properties

OpenMPswitch

Step B
Edit the BasicM.h file to include the file omp.h.
Edite el archivo BasicM.h para incluir el archivo omp.h.

BasicM.h
#pragma once //______________________________________ BasicM.h
#include "Resource.h"
#include "omp.h"
class BasicM: public Win::Dialog
{
     . . .
};


Step C
Edit the BasicM.cpp file as shown.
Edite el archivo BasicM.cpp cómo se muestra.

BasicM.cpp
. . .
void BasicM::Window_Open(Win::Event& e)
{
     wstring text;
     Mt::CriticalSection cs;
     //__________________________________________________ 1. Begin all the threads
     #pragma omp parallel
     {
          const int threadIndex = omp_get_thread_num();
          const int numThreads = omp_get_num_threads();
          wchar_t tmp[256];
          _snwprintf_s(tmp, 256, _TRUNCATE, L"threadIndex=%d\t\tnumThreads=%d\r\n", threadIndex, numThreads);
          cs.Enter();
          text += tmp;
          cs.Leave();
     }
     //__________________________________________________ 2. All threads have finished. Display
     tbxOutput.Text = text;
}


Tip
These are some functions of OpenMP:
  1. omp_set_num_threads() sets the number of threads.
  2. omp_get_num_threads() returns the number of threads. If you call this function inside a parallel block, it returns the number of threads inside the block. If you call this function outside a parallel block, it returns one.
  3. omp_get_thread_num() returns the thread index of the thread.
  4. omp_get_max_threads() returns the maximum number of threads.
  5. omp_in_parallel() returns one when the function is called inside a parallel block, otherwise returns zero.
  6. omp_set_dynamic() set the dynamic mode. In dynamic mode, the number of threads may be changed at different parallel blocks. To maintain the same number of threads, set this value to one.
  7. omp_get_dynamic() returns 1 if the dynamic mode is on, otherwise returns zero.
  8. omp_num_procs() returns the number of processors.

Estas son algunas funciones de OpenMP:

Problem 7
Create a Wintempla Dialog application called CaclPiM to repeat the program CaclPi using OpenMP. After creating the application, add a multi-line textbox called tbxOutput. Do not forget to adjust the properties of the project for OpenMP and run the Release version of the program.
Cree una aplicación de diálogo llamada CaclPiM para repetir el programa CaclPi usando OpenMP. Después de crear la aplicación, agregue una caja de texto de multi-línea llamada tbxOutput. No se olvide de ajustar las propiedades del proyecto para OpenMP y ejecutar la versión de Release del programa.

CalcPiMRun

Step A
Edit the CaclPiM.h file to include the file omp.h.
Edite el archivo CaclPiM.h para incluir el archivo omp.h.

CaclPiM.h
#pragma once //______________________________________ CaclPiM.h
#include "Resource.h"
#include "omp.h"
class CaclPiM: public Win::Dialog
{
     . . .
};


Step B
Edit the CaclPiM.cpp file as shown.
Edite el archivo CaclPiM.cpp cómo se muestra.

CaclPiM.cpp
. . .
void CaclPiM::Window_Open(Win::Event& e)
{
     Sys::Stopwatch sw;
     valarray<double> result(64);
     //__________________________________________________ 1. Begin all the threads
     #pragma omp parallel
     {
          const int threadIndex = omp_get_thread_num();
          const int numThreads = omp_get_num_threads();
          result[threadIndex] = 0.0;
          const size_t maxIterations = 99999999;
          const size_t first = Mt::WorkDistributionFirst(threadIndex, numThreads, maxIterations);
          const size_t last = Mt::WorkDistributionLast(threadIndex, numThreads, maxIterations);
          for (size_t i = first; i < last; i++)
          {
               //___________________________________________ 2. Perform partial calculation
               if (i%2 == 0)
                    result[threadIndex] += (1.0/(2*i+1));
               else
                    result[threadIndex] -= (1.0/(2*i+1));
          }
     }
     //__________________________________________________ 3. All threads have finished. Display
     tbxOutput.Text = sw.GetMillisecondsText();
     wchar_t text[32];
     _snwprintf_s(text, 32, _TRUNCATE, L"\r\n%.14f", 4.0*result.sum());
     tbxOutput.Text += text;
}


Problem 8
Create a Wintempla Dialog application called SimpleM to repeat the program Simple using OpenMP. After creating the application, add a multi-line textbox called tbxOutput. Do not forget to adjust the properties of the project for OpenMP and run the Release version of the program.
Cree una aplicación de diálogo llamada SimpleM para repetir el programa Simple usando OpenMP. Después de crear la aplicación, agregue una caja de texto de multi-línea llamada tbxOutput. No se olvide de ajustar las propiedades del proyecto para OpenMP y ejecutar la versión de Release del programa.

SimpleMRun

Step A
Edit the SimpleM.h file to include the file omp.h.
Edite el archivo SimpleM.h para incluir el archivo omp.h.

SimpleM.h
#pragma once //______________________________________ SimpleM.h
#include "Resource.h"
#include "omp.h"
class SimpleM: public Win::Dialog
{
     . . .
};


Step B
Edit the SimpleM.cpp file as shown.
Edite el archivo SimpleM.cpp cómo se muestra.

SimpleM.cpp
. . .
void SimpleM::Window_Open(Win::Event& e)
{
     Sys::Stopwatch sw;
     double result = 0.0;
     //__________________________________________________ 1. Begin all the threads
     #pragma omp parallel
     {
          double partialValue = 0.0;
          const int threadIndex = omp_get_thread_num();
          const int numThreads = omp_get_num_threads();
          const size_t maxIterations = 99999999;
          const size_t first = Mt::WorkDistributionFirst(threadIndex, numThreads, maxIterations);
          const size_t last = Mt::WorkDistributionLast(threadIndex, numThreads, maxIterations);
          for (size_t i = first; i < last; i++)
          {
               //_________________________________________ 2. Perform partial calculation
               if (i%2 == 0)
                    partialValue += (1.0/(2*i+1));
               else
                    partialValue -= (1.0/(2*i+1));
          }
          #pragma omp critical
          {
               result += partialValue;
          }
     }
     //__________________________________________________ 3. All threads have finished. Display
     tbxOutput.Text = sw.GetMillisecondsText();
     wchar_t text[32];
     _snwprintf_s(text, 32, _TRUNCATE, L"\r\n%.14f", 4.0*result);
     tbxOutput.Text += text;
}


#pragma omp critical

It is very similar to a critical section to get exclusive access to a block of code. If you are going to perform an increment, a decrement or something very simple, you can use #pragma omp atomic to change one shared variable as shown in the code below.
Es muy similar una sección crítica para obtener acceso exclusivo al bloque de código. Si usted va a realizar un incremento, un decremento o algo muy simple, usted puede usar #pragma omp atomic para cambiar una variable compartida como se muestra en el código debajo.

SimpleM.cpp
. . .
void SimpleM::Window_Open(Win::Event& e)
{
     Sys::Stopwatch sw;
     double result = 0.0;
     //__________________________________________________ 1. Begin all the threads
     #pragma omp parallel
     {
          . . .
          for (size_t i = first; i < last; i++)
          {
               //________________________________________ 2. Perform partial calculation
               if (i%2 == 0)
                    partialValue += (1.0/(2*i+1));
               else
                    partialValue -= (1.0/(2*i+1));
          }
          #pragma omp critical
          {
               result += partialValue;
          }
     }
     . . .
}


Tip
Steps to introduce parallel programming in your code:
  1. Find those loops that have a longer duration than other loops in the program
  2. Be sure that there are not dependencies between the computed values in the loop. That is, each iteration in the loop can be executed independently of other iterations in the loop. In some cases, you can modify the code inside the loop to remove these dependencies between the iterations.

  1. Encuentre aquellos for-loops que tienen una duración mas largar que otros for-loops en el programa
  2. Asegúrese que no hay dependencias entre los valores calculados en el for-loop. Esto es, cada iteración en el for-loop puede ser ejecutada independientemente de otras iteraciones en el for-loop. En algunos casos, usted puede modificar el código dentro del for-loop para remover estas dependencias entre las iteraciones.

Problem 9
Create a Wintempla Dialog application called SumaM to add two arrays using OpenMP. After creating the application, add a multi-line textbox called tbxOutput. Do not forget to adjust the properties of the project for OpenMP.
Cree una aplicación de diálogo llamada SumaM para sumar dos arreglos usando OpenMP. Después de crear la aplicación, agregue una caja de texto de multi-línea llamada tbxOutput. No se olvide de ajustar las propiedades del proyecto para OpenMP.

SumaMRun

Step A
Edit the SumaM.h file to include the file omp.h.
Edite el archivo SumaM.h para incluir el archivo omp.h.

SumaM.h
#pragma once //______________________________________ SumaM.h
#include "Resource.h"
#include "omp.h"
class SumaM: public Win::Dialog
{
     . . .
};


Step B
Edit the SumaM.cpp file as shown.
Edite el archivo SumaM.cpp cómo se muestra.

SumaM.cpp
. . .
void SumaM::Window_Open(Win::Event& e)
{
     int count = 30;
     valarray<double> a(count);
     valarray<double> b(count);
     valarray<double> c(count);
     //_________________________________________________ 1. Fill the vectors with random values using parallel programming
     int i;
     #pragma omp parallel for
     for (i = 0; i < count; i++)
     {
          a[i] = rand()/(double)RAND_MAX;
          b[i] = rand()/(double)RAND_MAX;
     }
     //_________________________________________________ 2. c = a + b using parallel programming
     #pragma omp parallel for
     for (i = 0; i < count; i++)
     {
          c[i] = a[i]+b[i];
     }
     //________________________________________________ 3. Display
     wchar_t text[32];
     wstring result;
     for (int i = 0; i < count; i++)
     {
          _snwprintf_s(text, 32, _TRUNCATE, L"%.3f \t + \t %.3f \t = %.3f\r\n", a[i], b[i], c[i]);
          result += text;
     }
     tbxOutput.Text = result;
}


Tip
Parallel programming introduces additional running to begin all the threads in the pool. You should use parallel programming only when the for-loop takes very long to execute.
La programación en paralelo introduce un tiempo adicional para iniciar todas las threads en el arreglo. Usted debe usar la programación en paralelo solamente cuando el for-loop toma un tiempo muy largo en su ejecución.

Problem 10
Create a Wintempla Dialog application called EasyPi to compute the value of π using OpenMP. After creating the application, add a multi-line textbox called tbxOutput. Do not forget to adjust the properties of the project for OpenMP and run the Release version of the program.
Cree una aplicación de diálogo llamada EasyPi para calcular el valor de π usando OpenMP. Después de crear la aplicación, agregue una caja de texto de multi-línea llamada tbxOutput. No se olvide de ajustar las propiedades del proyecto para OpenMP y ejecutar la versión de Release del programa.

EasyPiRun

Step A
Edit the EasyPi.h file to include the file omp.h.
Edite el archivo EasyPi.h para incluir el archivo omp.h.

EasyPi.h
#pragma once //______________________________________ EasyPi.h
#include "Resource.h"
#include "omp.h"
class EasyPi: public Win::Dialog
{
     . . .
};


Step B
Edit the EasyPi.cpp file as shown.
Edite el archivo EasyPi.cpp cómo se muestra.

EasyPi.cpp
. . .
void EasyPi::Window_Open(Win::Event& e)
{
     Sys::Stopwatch sw;
     double result = 0.0;
     const int maxIterations = 99999999;
     //_________________________________________________ 1. Begin parallel execution for addition of result
     int i;
     #pragma omp parallel for reduction (+:result) private(i)
     for (i = 0; i < maxIterations; i++)
     {
          if (i%2 == 0)
               result += (1.0/(2*i+1));
          else
               result -= (1.0/(2*i+1));
     }
     //________________________________________________ 2. Display
     tbxOutput.Text = sw.GetMillisecondsText();
     wchar_t text[32];
     _snwprintf_s(text, 32, _TRUNCATE, L"\r\n%.14f", 4.0*result);
     tbxOutput.Text += text;
}


for reduction

A reduction operator in OpenMP creates a variable to store the result for each thread, sets the initial value of this variable and combines the result of each thread.
Un operador de reducción en OpenMP crea una variable para almacenar el resultado para cada thread, fija el valor inicial de esta variable y combina el resultado de cada thread.

Command      Initial value  
#pragma omp parallel for reduction(+:variableName) 0
#pragma omp parallel for reduction(-:variableName) 0
#pragma omp parallel for reduction(*:variableName) 1
#pragma omp parallel for reduction(&:variableName) ~0
#pragma omp parallel for reduction(|:variableName) 0
#pragma omp parallel for reduction(&&:variableName) 1
#pragma omp parallel for reduction(||:variableName) 0
#pragma omp parallel for reduction(min:variableName) Largest positive number
#pragma omp parallel for reduction(max:variableName) Largest negative number

Problem 11
Search over the Internet about the application of
  1. #pragma omp barrier
  2. #pragma omp for nowait
  3. #pragma omp master
  4. #pragma omp single
  5. #pragma omp task
  6. #pragma omp taskwait
  7. #pragma omp sections
  8. #pragma omp section
  9. #pragma omp flush
  10. #pragma omp parallel private(variableName)
  11. #pragma omp parallel firstprivate(variableName)
  12. #pragma omp parallel lastprivate(variableName)
  13. #pragma omp parallel threadprivate(variableName)

Búsque en la Internet sobre el uso de

Problem 12
Search over the Internet about the application of
  1. omp_init_lock()
  2. omp_set_lock()
  3. omp_unset_lock()
  4. omp_destroy_lock()

Búsque en la Internet sobre el uso de

© Copyright 2000-2021 Wintempla selo. All Rights Reserved. Jul 22 2021. Home