Open main menu

CDOT Wiki β

Changes

Debugging Parallel Programs in Visual Studio / Team Debug

4,544 bytes added, 09:12, 22 December 2017
m
Walkthrough
1. When you start debug (F5), click on DEBUG > Windows > Processes.
 
2.
 
3. Terminate or Attach the process by using "Terminate Process" and "Attach to Process "icon.
'''How to Use:'''
Select threadsTerminate or Attach the process by using "Terminate Process" and "Attach to Process "icon.
==Threads window==
On the Threads window, you can see "main thread" line and some worker threads. The yellow arrow points only main thread. and go the next region. Apparently, ntdll.. threads are not used.
[[File:1stblock1stblock2.png|1000px|center|serial]]
You can see "Stack Frame" name on the top screen is changed to main\omp\1
On the Threads window, you can see "main thread" and other new three thread which same as default usable thread number 4 (The number is maximum usable thread of the cpu the program is running. And it is printed in the serial region as "omp_get_max_threads()"). after hitting 4 times (you can see the count on the breakpoint Window), the step goes to the next region.[[File:2ndtblockticon.png|50px|center|open]]A thread icon appear the side of the parallel line[[File:2ndblock2.png|1000px|center|open]]
You can see "Stack Frame" name on the top screen is changed to main\omp\2
On the Threads window, you can see "main thread" and other new seven thread which same as the thread number decided inside of the code. after hitting 8 times, the debugging is terminated.
[[File:3rdblock3rdblock2.png|1000px|center|open+]]
==Case B - Using the Parallel Stacks and the Parallel Watch Window==
==Case C==
We Each of these programs will use be a separate project.   <source lang="c">//Source1.cpp#include <iostream>#include <iomanip>#include <cstdlib>#include <chrono>#include <omp.h>#define NUM_THREADS 8using namespace std::chrono; // report system time//void reportTime(const char* msg, steady_clock::duration span) { auto ms = duration_cast<milliseconds>(span); std::cout << msg << " - took - " << ms.count() << " milliseconds" << std::endl;} int main(int argc, char** argv) { if (argc != 2) { std::cerr << argv[0] << ": invalid number of arguments\n"; std::cerr << "Usage: " << argv[0] << " no_of_slices\n"; return 1; } int n = std::atoi(argv[1]); steady_clock::time_point ts, te;  // calculate pi by integrating the following area under 1/(1 + x^2 programs ) in n steps ts = steady_clock::now(); int numThreads, f; double x, pi; double stepSize = 1.0 / (double)n; double sum[NUM_THREADS]; omp_set_num_threads(NUM_THREADS);#pragma omp parallel { int tid = omp_get_thread_num(); int nt = omp_get_num_threads(); if (tid == 0) numThreads = nt; sum[tid] = 0.0; for (int i = tid; i < n; i = i + nt) {  x = ((double)i + 0.5) * stepSize; sum[tid] += 4.0 / (1.0 + x * x); //std::cout << "THREAD" << tid << std::endl; } } int nt = omp_get_num_threads(); for (f = 0, pi = 0.0; f < numThreads; f++) { pi += sum[f] * stepSize; }  //pi = 4.0 * sum * stepSize; te = steady_clock::now();  std::cout << "n = " << n << std::fixed << std::setprecision(15) << "\n pi(exact) = " << 3.141592653589793 << "\n pi(calcd) = " << pi << std::endl; reportTime("Integration", te - ts);  // terminate char c; std::cout << "Press Enter key to debugg exit ... "; std::cin.get(c);} </source><source lang="c"> //Source2.cpp#include <iostream>#include <iomanip>#include <cstdlib>#include <chrono>#include <omp.h>#define PAD 8#define NUM_THREADS 1using namespace std::chrono; // report system time//void reportTime(const char* msg, steady_clock::duration span) { auto ms = duration_cast<milliseconds>(span); std::cout << msg << " - took - " << ms.count() << " milliseconds" << std::endl;} int main(int argc, char** argv) { if (argc != 2) { std::cerr << argv[0] << ": invalid number of arguments\n"; std::cerr << "Usage: " << argv[0] << " no_of_slices\n"; return 1; } int n = std::atoi(argv[1]); steady_clock::time_point ts, te;  // calculate pi by integrating the area under 1/(1 + x^2 processes) in n steps ts = steady_clock::now(); double x, pi = 0.0; double sum[NUM_THREADS][PAD]; double stepSize = 1.0 / (double)n; //double sumArr[8];  omp_set_num_threads(NUM_THREADS);#pragma omp parallel { int tid = omp_get_thread_num(); int nt = omp_get_num_threads();  for (int i = tid; i < n; i = i + nt) { x = ((double)i + 0.5) * stepSize; sum[tid][0] += 1.0 / (1.0 + x * x); //std::cout << "THREAD" << tid << std::endl; } }  for (int i = 0, pi = 0.0; i++;)pi += sum[i][0] * stepSize; //pi = 4.0 * sum * stepSize; te = steady_clock::now();  std::cout << "n = " << n << std::fixed << std::setprecision(15) << "\n pi(exact) = " << 3.141592653589793 << "\n pi(calcd) = " << pi << std::endl; reportTime("Integration", te - ts);
Each of these programs will be a separate project // terminate char c; std::cout << "Press Enter key to exit ... "; std::cin.get(c);}
There are two methods to debug multiple processes.</source>
We will create a seperate project for each of these pieces of code.
There are two methods to debug multiple processes.
'''Start Multiple Projects'''
First we need to put both of there projects in the same solution.
2.Go to "Add", then pick "Add Existing Project"
3.Navigate to the 2nd project's project file and open it
PIC[[File:Pr1.png|1000px|center|Process window]]  3.Navigate to the Source2 project's project file and open it  [[File:Pr2.png|600px|center|Process window]] 
Next we will have to set the 2nd Source2 project to start up with the 1st Source1 project
To do this we must:
2.Select Set Startup Projects
 
 
[[File:Pr3.png|1000px|center|Process window]]
 
3.On the Solution Propert Pages Window, Select Multiple startup projects
4.Select Start as the action for the 2nd Source2 Project
*Note:The Projects will execute in order shown
PIC
[[File:Pr4.png|600px|center|Process window]]  Now when we run the debugger, it will run both projects as a seperate processand will show up on the Processes window.  [[File:Pr5.png|1000px|center|Process window]]  The Processes Window will show: *Name: Name of the process*ID: Process ID*Path to the executable*Title: Menu Bar Title*State: Break or Running*Debugging:Debugging (Native, Managed, and so on.)*Connection Type: Transport type (default, native with no authentication)*Connection Target: Transport Qualifier (remote computer)   
'''Attach debugger to background process'''
First we must run the 2nd Source2 project without the debugger (VS 2017 will not allow you to attach as a running background process that is using the debugger).
1.Select Tools and pick External Tools
3.Give it a name and set command to C:\Windows\System32\cmd.exe
4.Apply changes and then under tools, select your commandline tool
[[File:Pr6.png|300px|center|Process window]]  4.Apply the changes and then under tools, select your command line tool 5.In the commandline, navigate to the 2nd Source2 project's debug folder*The executable should be located in the projects Debug folder*If there is no debug folder, you must run the Source2 project at least once 6.In the commandline, type the name of the Source2 project with the .exe extension and the appropriate agruements and the press enter to execute*IMPORTANT: Do not press enter to continue, Visual Studios only allow the debugger to attach to a running process  [[File:Pr7.png|600px|center|Process window]]
6.In the commandline, type the name of the 2nd project with the .exe extension
Now that your process is running, You can attach the debugger to it
To do this:
1.Start Debugging 2.Select Debug and pick Attach to Process  [[File:Pr8.png|1000px|center|Process window]]  3.In the Attach to Process window, select Source2 project's process and click attach  [[File:Pr9.png|600px|center|Process window]]
2.In the Attach to Process window, select 2nd project's process and click attach
Now your debugger will run the 1st Source1 project with 2nd Source2 project as a seperate process
[[File:Pr10.png|1000px|center|Process window]]
190
edits