Search code examples
multithreadingparallel-processingpthreadsopenmpllvm

Easiest way to make basic OpenMP like library


I would like to make a basic library with some very basic features of OpenMP. For example, just to be able to write a code like below. I wonder how I can use LLVM and pthreads to accomplish this. I guess there are two steps:

  1. Preprocessing to figure out the parallel task (parallel vs parallel-for)
  2. Convert appropriate code blocks to a void* function needed for pthreads
  3. Automation to create, run and join threads

Example code:

#Our_Own parallel
{
   printf("hello");
}

#Our_Own parallel for
for (int i =0; i < 1000; i++)
{
     printf(i);
}

Solution

  • DISCLAIMER: This is a very hard task, and there are many hidden tasks involved (how to access variables and set up their sharing attributes, implicit barriers, synchronization, etc.) I do not claim that you can solve all of them using the idea described below.

    If you use a (python) script to preprocess your code, here is a very minimal example how to start in C language (C++ may be a bit easier because of lambda functions).

    Use macro definitions (preferably put them in a header file) :

    // Macro definitions (in own.h)
    #define OWN_PARALLEL_BLOCK_START(f) \
    void *f(void * data) \
    {    \
        
    #define OWN_PARALLEL_BLOCK_END \
        return NULL; \
    }  
    
    #define OWN_PARALLEL_MAIN(f) \
    { \
        int THREAD_NUM=4;  \
        pthread_t thread_id[THREAD_NUM];  \
        for(int i=0;i<THREAD_NUM;i++) {  \
            pthread_create(&thread_id[i], NULL, f, NULL); \
        } \
        for(int i=0;i<THREAD_NUM;i++) { \
           pthread_join(thread_id[i], NULL); \
        } \
    }
    

    Your (python) script should convert this:

    int main(){
        #pragma own parallel
        {
           printf("Hello word\n");
        }
    }
    

    to the following:

    OWN_PARALLEL_BLOCK_START(ThreadBlock_1)
    {
       printf("Hello word\n");
    }
    OWN_PARALLEL_BLOCK_END
    
    int main(){
       OWN_PARALLEL_MAIN(ThreadBlock_1)    
    }
    

    Check it on Compiler Explorer