29 December 2018

C++ adaptation of Python Pool function

To achieve Python pool function

https://docs.python.org/2/library/multiprocessing.html

from multiprocessing import Pool

def f(x):
    return x*x

if __name__ == '__main__':
    p = Pool(5)
    print(p.map(f, [1, 2, 3]))

This is what I have come up with


 #include "stdafx.h"  
 #include <iostream>  
 #include <vector>  
 #include <unordered_map>  
 #include <mutex>  
 #include <windows.h>  
 #include <functional>   
 using namespace std;  
 std::mutex mtx1;  
 std::mutex mtx2;  
 unordered_map<int, double> A;  
 unordered_map<int, double> B;  
 typedef std::function<double(double)> funcDoubleToDouble;  
 DWORD_PTR createAffinityMask(int numCPU)  
 {  
      DWORD_PTR m = 0;  
      for (int i = 0; i < numCPU; i++)  
      {  
           DWORD_PTR temp = 1 << i;  
           m = m | temp;  
      }  
      return m;  
 }  
 double Square(double x)  
 {  
      return x * x;  
 }  
 void MapFunc(unordered_map<int, double>& source, unordered_map<int, double>& dest, int i, funcDoubleToDouble f, DWORD_PTR pmask)  
 {  
      //set processor affinity  
      HANDLE process = GetCurrentProcess();   
      BOOL success = SetProcessAffinityMask(process, pmask);  
      //lock global variables  
      mtx1.lock();  
      dest[i] = f(source[i]);  
      mtx1.unlock();  
      //unlock  
      //wait a little while to simulate processing  
      clock_t t = clock() + 100; // consume 100ms ...  
      while (clock() < t) {}       // of CPU time  
      printf("i %d:\tlogical CPU %d\tProcessId %d\n", i, GetCurrentProcessorNumber(), GetCurrentProcessId());  
 }  
 /*  
 map<int, double>& source - source map data  
 map<int, double>& dest - destination map data  
 funcDoubleToDouble f - mapping function  
 DWORD_PTR pmask - cpu processor mask (bitmapping)  
 */  
 void PoolMap(unordered_map<int, double>& source, unordered_map<int, double>& dest, funcDoubleToDouble f, DWORD_PTR pmask)  
 {  
      std::thread H[10];  
      for (int i = 0; i < 10; i++)  
      {  
           int index = i;  
           H[i]=thread(MapFunc, std::ref(source), std::ref(dest), i, f, pmask);  
      }  
      for (int i = 0; i < 10; i++)  
      {  
           H[i].join();  
      }  
      return;  
 }  
 int main()  
 {  
      unsigned num_cpus = std::thread::hardware_concurrency(); //retrieve the number of processors  
      DWORD_PTR pmask = createAffinityMask(5); // only use the first 5  
      std::cout << "CPU has " << num_cpus << " processors\n";  
      //initialize sourcevalues  
      for (int i=0;i<10;i++)  
      {  
           A[i] = (double) i;  
      }  
      //set pointer to the function we will use for mapping  
      funcDoubleToDouble f = Square;  
      PoolMap(A, B, f, pmask);  
      //show output of mapping function  
      for (int i = 0; i < 10; i++)  
      {  
           cout << i << ": " << B[i] << endl;  
      }  
      getchar();  
   return 0;  
 }  

No comments:

Post a Comment