我正在编写一个非常简单的强力程序。 我们的想法是拥有一个主线程,计算一个字符串的第一个字母,然后将它们填写为完整密码,以便将其与真实密码进行比较。
主题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秒。 :-(,以为现在感觉更“稳定”了!