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. |
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. |
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. |
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. |
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. |
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:
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. |
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. |
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:
|
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. |
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. |
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
Búsque en la Internet sobre el uso de |
Problem 12 |
Search over the Internet about the application of
Búsque en la Internet sobre el uso de |