Need help with counting within parallelized block - OpenMP/C-Programming


 
Thread Tools Search this Thread
Top Forums Programming Need help with counting within parallelized block - OpenMP/C-Programming
# 1  
Old 10-09-2014
Need help with counting within parallelized block - OpenMP/C-Programming

Hello together,

I have a question for you. Since a few weeks I am trying to programm
a small bruteforce application in C on Ubuntu 14.04.1 using Code::Blocks
with gcc-4.8.2. My programm is nothing special. It's just for practise,
Without hashing or something like that. For me the focus is on parallelize
the procedure that generates words. I'm using OpenMP for this small project.
Until now it works good for me. There is just one thing that I would like to
implement, but without success so far.

I want that my programm counts all the generated words, regardless of wether
the search string was found or not. I hope you understand what I'm talking
about. I'm sorry for my bad english. I am from germany.

I declared a global unsigned integer variable with the name 'Counter' for counting all
the generated words.
Because the whole procedure is parallelized, the variable is specified as reduction
variable.
Code:
#pragma omp parallel default... reduction ( +: Counter )

So the problem is, that the reduction is not completed until the end of the parallel region,
when the search string was found.
That means only when my programm doesn't have a match, at the end the number of counts for
all generated words is correct. Why? Because when nothing was found, the application reaches
the end of the parallel region and the reduction is completed.
But if my programm has a match, the number of counts is always wrong at the output.

Now, I would like to know, if there is way to exit sane and portable from a parallel region,
without have to wait until all possibilites of words has been tried? Do you understand
what I mean? I.e. we are searching the following string: "4788". I tell my programm the max.
length of words should be 4. From "0" until "9999" altogether are 11110 tries, using just
digits (0123456789) for the brute force procedure. If the word is found, the number of tries (counts)
is 5899.
Is it possible to exit sane and portable from a parallel region earlier?
I.e. when the search string was found? By the same behavior like if nothing was found? So that at the end
the number of counts will displayed correct, even if the word was found?

I have tried something with two variables 'CheckStatus' and 'MyCheckStatus'. This variables should indicate
when work is done (i.e. if there's a match).
With omp atomic read and omp atomic write. But unfortunately without success.

Here is my source code:
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <omp.h>

/* Global variables */

const char         Literals[]    = "0123456789";
const unsigned int NLiterals     = sizeof( Literals ) - 1;
const char         TestString[]  = "4788";
char               EndString[16];

int CheckStatus = 0;

/* Functions */

static void BruteForcer( const int *, const int *, int, unsigned * );

int main()
{
    unsigned Counter = 0;

    #pragma omp parallel default( none ) shared( CheckStatus ) reduction( +:Counter )
    {
        for( int WordLength = 0; WordLength < 5; ++WordLength )
        {
            int FirstEntry[WordLength], LastEntry[WordLength], MyCheckStatus;

            for( int j = 0; j < WordLength; ++j )
                FirstEntry[j] = LastEntry[j] = 0;

            #pragma omp for schedule( dynamic )
            for( int i = 0; i < NLiterals; ++i )
            {
                FirstEntry[0] = i;
                LastEntry[0]  = i + 1;
                #pragma omp atomic read
                MyCheckStatus = CheckStatus;
                if( !MyCheckStatus )
                    BruteForcer( FirstEntry, LastEntry, WordLength, &Counter );
            }
        }
    }

    if( CheckStatus )
        fprintf( stdout, "\nWord found: '%s'! %u tries.\n", EndString, Counter );

    else
        fprintf( stdout, "\nNothing found: '%s'! %u tries.\n", "Empty", Counter );

    exit( EXIT_SUCCESS );
}

static void BruteForcer( const int *FstEntry, const int *LstEntry, int WdLength, unsigned *CounterPtr )
{
    char Word[WdLength];
    int  Entry[WdLength + 1];
    int  i, j;

    memset( Entry, '\0', WdLength );

    /* copy FstEntry to Entry */
    for( i = 0; i < WdLength; ++i )
        Entry[i] = FstEntry[i];

    i = 0;

    while( i < WdLength )
    {
        /* generate word */
        for( i = 0; i < WdLength; ++i )
            Word[i] = Literals[Entry[i]];

        /* null-byte at end of string */
        Word[WdLength] = '\0';

        ++*CounterPtr;

        /* string compare */
        if( strncmp( TestString, Word, sizeof( TestString ) ) == 0 )
        {
            strncpy( EndString, Word, strlen( Word ) );
            #pragma omp atomic write
            CheckStatus = 1;
            return;
        }

        /* increment Entry */
        for( i = 0; i < WdLength && ++Entry[WdLength-i-1] == NLiterals; i++ )
            Entry[WdLength-i-1] = 0;

        /* when Entry != LstEntry then leave loop */
        for( j = 0; j < WdLength; ++j )
            if( Entry[j] != LstEntry[j] )
                break;

        /* when Entry == LstEntry leave function */
        if( j == WdLength )
            return;
    }
}

Without parallelization I have this output:
Code:
Word found: '4788' ! 5899 tries!

That is correct. But with parallelization the output is as follows:
Code:
Word found: '4788' ! 10899 tries! (Each time the number is another!)

The goal is, that the number of counts is always correct with parallelization.
Please could you help me with this issue? If possible with small code examples or improving my source code, too. I would be very very appreciated.

DaveX

Last edited by DaveX; 10-10-2014 at 02:54 AM.. Reason: Change PHP tags to CODE tags.
# 2  
Old 10-09-2014
It took me a while to realize what you were getting at.

The count isn't wrong so to speak. If it launches 12 threads at once, the 1st of which finds your value, that doesn't mean the other 11 never ran.

If you want the exact context you found it, you should only set a value when you find it.
# 3  
Old 10-10-2014
Hello,

thank you for your replying.
Quote:
Originally Posted by Corona688
The count isn't wrong so to speak. If it launches 12 threads at once, the 1st of which finds your value, that doesn't mean the other 11 never ran.
Yes, I know this. Smilie But this is not the problem.
As I already wrote, the problem is that I would like to know, how to reach that even though the programm has a match, it shows the correct number of counts. In order that it works, I have to find a way the application exits the parallelized block once the word is found. But with the same behavior as it'd not find anything. Because how I already explained, the correct number of counts is displayed only if the end of the parallelized block was reached. Only thus the reduction can complete.

Last edited by DaveX; 10-10-2014 at 05:02 AM..
# 4  
Old 10-10-2014
My point is, count isn't wrong as much as completely meaningless. The order your threads run in isn't absolute. Thread #5 could run before thread #1, succeed, and return a count of 1! If you want the threads to know what order they are, you'll have to tell them.

Increment outside the parallel section and feed that value into the function as a parameter. If the function succeeds, have it set a flag variable to the correct 'count' value. Other threads can check that flag variable before their loop, and quit early if nonzero.

Last edited by Corona688; 10-10-2014 at 12:46 PM..
# 5  
Old 10-10-2014
Quote:
Originally Posted by Corona688
My point is, count isn't wrong as much as completely meaningless. The order your threads run in isn't absolute. Thread #5 could run before thread #1, succeed, and return a count of 1!
I know. That's the reason why I specified 'Counter' as a reduction variable. But you're right. My implementation doesn't do what I expect. So I would try to implement your suggestions.
Quote:
Originally Posted by Corona688
If you want the threads to know what order they are, you'll have to tell them.
Could you show me how to do this? Maybe a small code example?
Quote:
Originally Posted by Corona688
Increment outside the parallel section and feed that value into the function as a parameter. If the function succeeds, have it set a flag variable to the correct 'count' value. Other threads can check that flag variable before their loop, and quit early if nonzero.
I will try to do this. Could you help me? Maybe I would understand it better if you could give a small example. If you want?

Last edited by DaveX; 10-10-2014 at 01:39 PM..
# 6  
Old 10-10-2014
I don't understand this multithreading library in particular, just multithreading in general, so I can't give you OMP code, but I can show you the concept of what I mean:

Code:
int flag=-1;

while(flag < 0) {
        function(count, &flag);
        count++;
}

void parallel_function(int count, int *flag) {
        char str[10];
        int c=count;

        if( (*flag) >= 0) return;

        memset(str, 0, sizeof(str));

        // Compute the string from the value of 'c'.  Each different
        // count will give a unique solution.
        int length=(c%5)+1;
        c /= 5;

        for(int n=0; n<length; n++)
        {
                str[n]=Literals[c%Nliterals];
                c /= Nliterals;
        }

        // If and only if we have the correct solution, store the value.
        if(string_matches)
                (*flag)=count;
}

You can run that in parallel and not have 5000 "wrong" threads upsetting the value of 'flag', since it only gets set on success. And order is irrelevant since each thread is told exactly what its number is.

The size of an integer limits the number of unique digit strings you can create, but that was also true before. (i.e. a 30-digit string has 10^30 possibilities, an integer only holds up to 2^31) You could use more complicated things than a single int -- like an array of integers, one for each digit -- but the principle remains the same.

Last edited by Corona688; 10-10-2014 at 01:54 PM..
This User Gave Thanks to Corona688 For This Post:
# 7  
Old 10-10-2014
Cool. Smilie Thank you very much. Smilie Now I know what you mean. I will try to implement it in my source code. That is a really good idea. Thanks a lot. Later I will post my modified source.
Login or Register to Ask a Question

Previous Thread | Next Thread

8 More Discussions You Might Find Interesting

1. Programming

OpenMP and MPI hybrid thread numbers

hi, I have two basic questions, I will be really grateful if I receive any comment from you, I have an MPI code where I am trying to implement OpenMP directives. The machine where I run the code has 16 cores. I run the code with export OMP_NUM_THREADS=2 mpirun -np 4 ./exec If I... (0 Replies)
Discussion started by: armando_2011
0 Replies

2. Programming

Undefined reference to omp_get_thread_num using OpenMP?

I am using a large code-base that compiled successfully before using make with a makefile and cmake. However, now that I'm trying to use openmp with it, I'm now getting the errors undefined reference to `omp_get_thread_num' undefined reference to `omp_get_num_threads'I don't think this... (0 Replies)
Discussion started by: larry burns
0 Replies

3. Programming

Gcc openmp programming problem

Dear Linux users, I'm a noob at openmp, gcc and c programming. I can run my own openmp code in terminal with no problem, eg. gcc -fopenmp program.c -o program. But now I'm trying to compile and run another person's code, it contains a makefile and multiple .c and .h files. I don't know how to... (2 Replies)
Discussion started by: pigeon151
2 Replies

4. Programming

Building Block style programming Book

Hello to all, Here is my situation. Some time in the mid-80's I stumbled across a small white programming book - can't remember the name but it was unique in that it started right out giving instructions on creating building blocks in code as a foundation for a complete system. The book was... (2 Replies)
Discussion started by: jozefn
2 Replies

5. HP-UX

Spawn more than 8 threads OpenMP & HPUX

Hi folks, I am trying to run more than 8 threads in OpenMP team on my HP-UX 11i v3 system (without root access), but NO success. Compiler: aCC A.06.26 I tried to setup: OMP_NUM_THREADS, omp_set_num_threads(), max_thread_proc=1000, nkthread=8416, set_dynamic=0 Machine has 2 processors... (1 Reply)
Discussion started by: ATveretinov
1 Replies

6. Shell Programming and Scripting

Counting lines in each block file

hello im new here so i want to say hi everybody :) i have to write a script and im newbie :/ i hope that in this forum are many ppl who knows subject :) i have hundrets folders. in each folder is a file name trace.txt. each trace.txt has a lot of tracert's results separates with "-----" it... (6 Replies)
Discussion started by: michael8484
6 Replies

7. UNIX for Dummies Questions & Answers

gzip parallelized

Hello everyone, I've got a question regarding the gzip command. I regulary use gzip to pack huge ammounts of files. Is it ok to start 'gzip *' several times in the same directory to parallelize the packing process or can this result in problems, e.g. broken or unpacked files? My tests... (7 Replies)
Discussion started by: Basch
7 Replies

8. UNIX for Dummies Questions & Answers

Carreer:Networking Programming in Unix (C programming Language)

Hello, I am trying to learn Networking Programming in C in unix enviorment. I want to know how good it is to become a network programmer. i am crazy about Network programming but i also want to opt for the best carreer options. Anybody experienced Network Programmer, please tell me is my... (5 Replies)
Discussion started by: vibhory2j
5 Replies
Login or Register to Ask a Question