每个线程的OpenMP递归变慢

时间:2014-12-13 20:04:38

标签: c recursion openmp

我正在编写一个非常简单的强力程序。 我们的想法是拥有一个主线程,计算一个字符串的第一个字母,然后将它们填写为完整密码,以便将其与真实密码进行比较。

主题1:aaaaa到azzzz

主题2:baaaa到bzzzz

等,仅在检查小写字母时。

使用递归方法完成完成。线程得到他的第一个字母(a)并调用程序,构建aaaaa,aaaab,aaaac,aaaad .. azzzy,azzzz。

问题是,每个线程的递归过程变慢。我的系统是一个四核CPU,但即使用2个线程运行它也会减慢6个字母的过程,从大约20秒到38秒,随机甚至1分30秒。

我实际上认为这会是内存访问的一些问题,但我找不到它。 时间仅针对程序本身进行测量,因此周围的任何东西都不应该干扰它。代码看起来可能有点f * cked up,因为我已经尝试了很多不同的东西,移动部件,插入输出以进行检查等等。抱歉。

这是我的代码:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <omp.h>

static void bruteForce(char* currentPW, int index, int PWLength, char* alphabet, int* alphabetSize);
char alphabet[] =   "abcdefghijklmnopqrstuvwxyz"
                    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
                    "-+,;.:_!§$%&=*<>"
                    "0123456789";
int alphabetSize;
time_t gStartTime, gEndTime;
int omp_get_num_threads(void);

int main(int argc, char **argv)
{
    int PWLength = 9;
    int i = 0;
    int currentPWLength;
    omp_set_dynamic(0);     // Explicitly disable dynamic teams

    // Timer starten
    time( &gStartTime );

    for(currentPWLength = 6; currentPWLength <= PWLength; ++currentPWLength )
    {
        // Create teams
        #pragma omp parallel private(alphabetSize) num_threads(2)
        {
            alphabetSize = sizeof(alphabet) - 1;
            // We will copy the alphabet in our own memory, so there is no race condition
            char* threadAlphabet = malloc(sizeof(alphabet));
            strncpy(threadAlphabet, alphabet, alphabetSize);

            // Only one thread will do this
            #pragma omp single nowait
            for( i = 0; i < alphabetSize; ++i )
            {
                int j = 0;
                // We will store the startStrings in memory
                // This could be also done in an array, but at this point we do not need a
                // structure.
                char* startString = malloc(currentPWLength + 1);
                startString[0] = alphabet[i];
                for(j = 1; j <= currentPWLength; j++)
                    startString[j] = '\0';

                // At this point there will be 30 tasks to be solved.
                // Each team member can be assigned to a task.
                // This way we can split up the tasks to all members even in a single "Umgebung"
                // Note: Not NUMA friendly, but very fast as no new threads (HUGE overload!)
                //        have to be created
                #pragma omp task
                {
                    // Just some debug
                    printf("I am number %d and and my startString = %s\n", omp_get_thread_num(), startString);
                    double tOmpStartTime = omp_get_wtime();

                    // This will run the BruteForce algorithm
                    bruteForce(startString, 1, currentPWLength, &*threadAlphabet, &alphabetSize);

                    // More debug
                    double tOmpEndTime = omp_get_wtime();
                    double tDifTime = tOmpEndTime-tOmpStartTime;
                    printf("Number %d finished: Time: \t %f \n", omp_get_thread_num(), tDifTime);

                    // Give allocated memory free
                    free(startString);
                }
            }
        }
    }

    // Timer stoppen
    time( &gEndTime );
    printf("Elapsed time: %ds", gEndTime-gStartTime);

    puts( "!!! Passwort nicht gefunden !!!" );

    return EXIT_FAILURE;
}

和暴力程序:

void bruteForce(char* currentPW, int index, int PWLength, char* alphabet, int* alphabetSize)
{
    // Loop through all letters to append them
    int i = 0;
    for (i = 0; i < *alphabetSize; ++i)
    {
        // Append
        currentPW[index] = alphabet[i];

        if (index == PWLength - 1)
        {
            static const char* gPW = "Aaa3b5";
            // We can not use strcmp function here, as it can cause memory race conditions.
            // Therefore an own version below.
            const unsigned char *p1 = (const unsigned char *)currentPW;
            const unsigned char *p2 = (const unsigned char *)gPW;
            int equal = 1;

            while (*p1 != '\0')
            {
                if (*p2 == '\0' || *p2 != *p1)
                {
                    equal = -1;
                    break;
                }
                p1++;
                p2++;
            }
            if (*p2 != '\0')
                equal = -1;

            else if(equal == 1)
            {
                // Password found
                // Print information and escape
                printf("Passwort = %s!\n", currentPW);
                // Timer stoppen
                time( &gEndTime );
                printf("Elapsed time: %ds\n", gEndTime-gStartTime);

                exit(0);
            }
        }
        // We haven't appent enough, increase index and run again
        else bruteForce(currentPW, index + 1, PWLength, alphabet, alphabetSize);
    }
}

使用1个线程记录:

Password length = 6
I am number 0 and have i = 0 and my startString = a
Number 0 finished: 0 minutes 13 seconds
I am number 0 and have i = 1 and my startString = b
Number 0 finished: 0 minutes 12 seconds
I am number 0 and have i = 2 and my startString = c
Number 0 finished: 0 minutes 12 seconds
I am number 0 and have i = 3 and my startString = d
Number 0 finished: 0 minutes 12 seconds
I am number 0 and have i = 4 and my startString = e
Number 0 finished: 0 minutes 13 seconds
I am number 0 and have i = 5 and my startString = f
Number 0 finished: 0 minutes 12 seconds
I am number 0 and have i = 6 and my startString = g
Number 0 finished: 0 minutes 12 seconds
I am number 0 and have i = 7 and my startString = h
Number 0 finished: 0 minutes 12 seconds
I am number 0 and have i = 8 and my startString = i
Number 0 finished: 0 minutes 12 seconds
I am number 0 and have i = 9 and my startString = j
Number 0 finished: 0 minutes 12 seconds
I am number 0 and have i = 10 and my startString = k
Number 0 finished: 0 minutes 13 seconds
I am number 0 and have i = 11 and my startString = l
Number 0 finished: 0 minutes 12 seconds
I am number 0 and have i = 12 and my startString = m
Number 0 finished: 0 minutes 12 seconds
I am number 0 and have i = 13 and my startString = n
Number 0 finished: 0 minutes 12 seconds
I am number 0 and have i = 14 and my startString = o
Number 0 finished: 0 minutes 13 seconds
I am number 0 and have i = 15 and my startString = p
Number 0 finished: 0 minutes 12 seconds
I am number 0 and have i = 16 and my startString = q
Number 0 finished: 0 minutes 13 seconds
I am number 0 and have i = 17 and my startString = r
Number 0 finished: 0 minutes 12 seconds
I am number 0 and have i = 18 and my startString = s
Number 0 finished: 0 minutes 13 seconds
I am number 0 and have i = 19 and my startString = t
Number 0 finished: 0 minutes 12 seconds
I am number 0 and have i = 20 and my startString = u
Number 0 finished: 0 minutes 12 seconds
I am number 0 and have i = 21 and my startString = v
Number 0 finished: 0 minutes 12 seconds
I am number 0 and have i = 22 and my startString = w
Number 0 finished: 0 minutes 13 seconds
I am number 0 and have i = 23 and my startString = x
Number 0 finished: 0 minutes 12 seconds
I am number 0 and have i = 24 and my startString = y
Number 0 finished: 0 minutes 12 seconds
I am number 0 and have i = 25 and my startString = z
Number 0 finished: 0 minutes 13 seconds
I am number 0 and have i = 26 and my startString = A
Number 0 finished: 0 minutes 13 seconds
I am number 0 and have i = 27 and my startString = B
Number 0 finished: 0 minutes 12 seconds
I am number 0 and have i = 28 and my startString = C
Number 0 finished: 0 minutes 12 seconds
I am number 0 and have i = 29 and my startString = D
Number 0 finished: 0 minutes 13 seconds
I am number 0 and have i = 30 and my startString = E
Number 0 finished: 0 minutes 12 seconds
I am number 0 and have i = 31 and my startString = F
Number 0 finished: 0 minutes 12 seconds
I am number 0 and have i = 32 and my startString = G
Number 0 finished: 0 minutes 12 seconds
I am number 0 and have i = 33 and my startString = H
Number 0 finished: 0 minutes 13 seconds
I am number 0 and have i = 34 and my startString = I
Number 0 finished: 0 minutes 12 seconds
I am number 0 and have i = 35 and my startString = J
Number 0 finished: 0 minutes 12 seconds
I am number 0 and have i = 36 and my startString = K
Number 0 finished: 0 minutes 13 seconds
I am number 0 and have i = 37 and my startString = L
Number 0 finished: 0 minutes 12 seconds
I am number 0 and have i = 38 and my startString = M
Number 0 finished: 0 minutes 12 seconds
I am number 0 and have i = 39 and my startString = N
Number 0 finished: 0 minutes 12 seconds
I am number 0 and have i = 40 and my startString = O
Number 0 finished: 0 minutes 13 seconds
I am number 0 and have i = 41 and my startString = P
Number 0 finished: 0 minutes 12 seconds
I am number 0 and have i = 42 and my startString = Q
Number 0 finished: 0 minutes 12 seconds
I am number 0 and have i = 43 and my startString = R
Number 0 finished: 0 minutes 13 seconds
I am number 0 and have i = 44 and my startString = S
Number 0 finished: 0 minutes 12 seconds
I am number 0 and have i = 45 and my startString = T
Number 0 finished: 0 minutes 12 seconds
I am number 0 and have i = 46 and my startString = U
Number 0 finished: 0 minutes 12 seconds
I am number 0 and have i = 47 and my startString = V
Number 0 finished: 0 minutes 13 seconds
I am number 0 and have i = 48 and my startString = W
Number 0 finished: 0 minutes 12 seconds
I am number 0 and have i = 49 and my startString = X
Number 0 finished: 0 minutes 12 seconds
I am number 0 and have i = 50 and my startString = Y
Number 0 finished: 0 minutes 13 seconds
I am number 0 and have i = 51 and my startString = Z
Number 0 finished: 0 minutes 12 seconds
I am number 0 and have i = 52 and my startString = -
Number 0 finished: 0 minutes 12 seconds
I am number 0 and have i = 53 and my startString = +
Number 0 finished: 0 minutes 12 seconds
I am number 0 and have i = 54 and my startString = ,
Number 0 finished: 0 minutes 13 seconds
I am number 0 and have i = 55 and my startString = ;
Number 0 finished: 0 minutes 12 seconds
I am number 0 and have i = 56 and my startString = .
Number 0 finished: 0 minutes 13 seconds
I am number 0 and have i = 57 and my startString = :
Number 0 finished: 0 minutes 12 seconds
I am number 0 and have i = 58 and my startString = _
Number 0 finished: 0 minutes 12 seconds
I am number 0 and have i = 59 and my startString = !
Number 0 finished: 0 minutes 13 seconds
I am number 0 and have i = 60 and my startString = ยบ
Number 0 finished: 0 minutes 12 seconds
I am number 0 and have i = 61 and my startString = $
Number 0 finished: 0 minutes 12 seconds
I am number 0 and have i = 62 and my startString = %
Number 0 finished: 0 minutes 13 seconds
I am number 0 and have i = 63 and my startString = &
Number 0 finished: 0 minutes 12 seconds
I am number 0 and have i = 64 and my startString = =
Number 0 finished: 0 minutes 12 seconds
I am number 0 and have i = 65 and my startString = *
Number 0 finished: 0 minutes 12 seconds
I am number 0 and have i = 66 and my startString = <
Number 0 finished: 0 minutes 13 seconds
I am number 0 and have i = 67 and my startString = >
Number 0 finished: 0 minutes 12 seconds
I am number 0 and have i = 68 and my startString = 0
Number 0 finished: 0 minutes 12 seconds
I am number 0 and have i = 69 and my startString = 1
Number 0 finished: 0 minutes 12 seconds
I am number 0 and have i = 70 and my startString = 2
Number 0 finished: 0 minutes 12 seconds
I am number 0 and have i = 71 and my startString = 3
Number 0 finished: 0 minutes 13 seconds
I am number 0 and have i = 72 and my startString = 4
Number 0 finished: 0 minutes 12 seconds
I am number 0 and have i = 73 and my startString = 5
Number 0 finished: 0 minutes 12 seconds
I am number 0 and have i = 74 and my startString = 6
Number 0 finished: 0 minutes 12 seconds
I am number 0 and have i = 75 and my startString = 7
Number 0 finished: 0 minutes 12 seconds
I am number 0 and have i = 0 and my startString = a
Number 0 finished: 15 minutes 51 seconds
I am number 0 and have i = 1 and my startString = b
Number 0 finished: 16 minutes 42 seconds
I am number 0 and have i = 2 and my startString = c
Number 0 finished: 16 minutes 43 seconds
I am number 0 and have i = 3 and my startString = d
Number 0 finished: 15 minutes 56 seconds

使用4个线程记录:

Password length = 6
I am number 1 and have i = 0 and my startString = a
I am number 3 and have i = 3 and my startString = d
I am number 2 and have i = 2 and my startString = c
I am number 0 and have i = 1 and my startString = b
Number 1 finished: 0 minutes 12 seconds
I am number 1 and have i = 4 and my startString = e
Number 1 finished: 1 minutes 11 seconds
I am number 1 and have i = 5 and my startString = f
Number 0 finished: 2 minutes 3 seconds
I am number 0 and have i = 6 and my startString = g
Number 3 finished: 2 minutes 16 seconds
I am number 3 and have i = 7 and my startString = h
Number 2 finished: 2 minutes 26 seconds
I am number 2 and have i = 8 and my startString = i
Number 1 finished: 1 minutes 11 seconds
I am number 1 and have i = 9 and my startString = j
Number 0 finished: 0 minutes 38 seconds
I am number 0 and have i = 10 and my startString = k
Number 3 finished: 0 minutes 51 seconds
I am number 3 and have i = 11 and my startString = l
Number 2 finished: 1 minutes 2 seconds
I am number 2 and have i = 12 and my startString = m
Number 2 finished: 0 minutes 30 seconds
I am number 2 and have i = 13 and my startString = n
Number 2 finished: 0 minutes 29 seconds
I am number 2 and have i = 14 and my startString = o
Number 0 finished: 1 minutes 51 seconds
I am number 0 and have i = 15 and my startString = p
Number 1 finished: 2 minutes 8 seconds
I am number 1 and have i = 16 and my startString = q
Number 3 finished: 1 minutes 36 seconds
I am number 3 and have i = 17 and my startString = r
Number 3 finished: 0 minutes 26 seconds
I am number 3 and have i = 18 and my startString = s
Number 2 finished: 0 minutes 44 seconds
I am number 2 and have i = 19 and my startString = t
Number 0 finished: 0 minutes 55 seconds
I am number 0 and have i = 20 and my startString = u
Number 1 finished: 0 minutes 48 seconds
I am number 1 and have i = 21 and my startString = v
Number 2 finished: 1 minutes 10 seconds
I am number 2 and have i = 22 and my startString = w
Number 3 finished: 1 minutes 15 seconds
I am number 3 and have i = 23 and my startString = x
Number 3 finished: 0 minutes 29 seconds
I am number 3 and have i = 24 and my startString = y
Number 0 finished: 1 minutes 34 seconds
I am number 0 and have i = 25 and my startString = z
Number 1 finished: 1 minutes 43 seconds
I am number 1 and have i = 26 and my startString = A
Number 2 finished: 0 minutes 56 seconds
I am number 2 and have i = 27 and my startString = B
Number 3 finished: 0 minutes 45 seconds
I am number 3 and have i = 28 and my startString = C
Number 3 finished: 0 minutes 31 seconds
I am number 3 and have i = 29 and my startString = D
Number 0 finished: 1 minutes 39 seconds
I am number 0 and have i = 30 and my startString = E
Number 3 finished: 0 minutes 32 seconds
I am number 3 and have i = 31 and my startString = F
Number 2 finished: 1 minutes 37 seconds
I am number 2 and have i = 32 and my startString = G
Number 1 finished: 1 minutes 42 seconds
I am number 1 and have i = 33 and my startString = H
Number 1 finished: 0 minutes 30 seconds
I am number 1 and have i = 34 and my startString = I
Number 0 finished: 0 minutes 47 seconds
I am number 0 and have i = 35 and my startString = J
Number 3 finished: 0 minutes 57 seconds
I am number 3 and have i = 36 and my startString = K
Number 2 finished: 0 minutes 47 seconds
I am number 2 and have i = 37 and my startString = L
Number 1 finished: 1 minutes 33 seconds
I am number 1 and have i = 38 and my startString = M
Number 0 finished: 1 minutes 33 seconds
I am number 0 and have i = 39 and my startString = N
Number 0 finished: 0 minutes 12 seconds
I am number 0 and have i = 40 and my startString = O
Number 2 finished: 1 minutes 39 seconds
I am number 2 and have i = 41 and my startString = P
Number 3 finished: 1 minutes 44 seconds
I am number 3 and have i = 42 and my startString = Q
Number 1 finished: 0 minutes 33 seconds
I am number 1 and have i = 43 and my startString = R
Number 1 finished: 0 minutes 28 seconds
I am number 1 and have i = 44 and my startString = S
Number 0 finished: 1 minutes 7 seconds
I am number 0 and have i = 45 and my startString = T
Number 1 finished: 0 minutes 29 seconds
I am number 1 and have i = 46 and my startString = U
Number 3 finished: 1 minutes 6 seconds
I am number 3 and have i = 47 and my startString = V
Number 2 finished: 1 minutes 12 seconds
I am number 2 and have i = 48 and my startString = W
Number 2 finished: 0 minutes 21 seconds
I am number 2 and have i = 49 and my startString = X
Number 0 finished: 0 minutes 45 seconds
I am number 0 and have i = 50 and my startString = Y
Number 2 finished: 0 minutes 41 seconds
I am number 2 and have i = 51 and my startString = Z
Number 1 finished: 1 minutes 11 seconds
I am number 1 and have i = 52 and my startString = -
Number 3 finished: 1 minutes 11 seconds
I am number 3 and have i = 53 and my startString = +
Number 0 finished: 0 minutes 59 seconds
I am number 0 and have i = 54 and my startString = ,
Number 0 finished: 0 minutes 28 seconds
I am number 0 and have i = 55 and my startString = ;
Number 0 finished: 0 minutes 28 seconds
I am number 0 and have i = 56 and my startString = .
Number 3 finished: 1 minutes 25 seconds
I am number 3 and have i = 57 and my startString = :
Number 2 finished: 1 minutes 38 seconds
I am number 2 and have i = 58 and my startString = _
Number 1 finished: 1 minutes 36 seconds
I am number 1 and have i = 59 and my startString = !
Number 1 finished: 0 minutes 29 seconds
I am number 1 and have i = 60 and my startString = º
Number 0 finished: 1 minutes 6 seconds
I am number 0 and have i = 61 and my startString = $
Number 1 finished: 0 minutes 35 seconds
I am number 1 and have i = 62 and my startString = %
Number 3 finished: 1 minutes 26 seconds
I am number 3 and have i = 63 and my startString = &
Number 2 finished: 1 minutes 20 seconds
I am number 2 and have i = 64 and my startString = =
Number 2 finished: 0 minutes 20 seconds
I am number 2 and have i = 65 and my startString = *
Number 0 finished: 0 minutes 48 seconds
I am number 0 and have i = 66 and my startString = <
Number 1 finished: 0 minutes 55 seconds
I am number 1 and have i = 67 and my startString = >
Number 3 finished: 0 minutes 47 seconds
Password length = 7
I am number 2 and have i = 0 and my startString = a
I am number 3 and have i = 1 and my startString = b
I am number 1 and have i = 2 and my startString = c
I am number 0 and have i = 3 and my startString = d
Number 0 finished: 26 minutes 32 seconds
I am number 0 and have i = 4 and my startString = e
Number 0 finished: 25 minutes 50 seconds
I am number 0 and have i = 5 and my startString = f
Number 2 finished: 54 minutes 8 seconds
I am number 2 and have i = 6 and my startString = g
Number 3 finished: 72 minutes 27 seconds
I am number 3 and have i = 7 and my startString = h
Number 1 finished: 75 minutes 45 seconds
I am number 1 and have i = 8 and my startString = i
Number 0 finished: 53 minutes 6 seconds

编辑:我已更新我的代码并将所有变量从全局移动到线程内存。实际上我希望以这种方式解决我的问题,因为我认为这将是某种竞争条件。但它仍然需要随机超过1分钟而不是20秒。 :-(,以为现在感觉更“稳定”了!

0 个答案:

没有答案