C++中的GPU加速递归函数
GPU accelerated recursive function in C++
我是 C++ 的新手(实际上才两天),我想知道是否可以使用此代码进行一些并行化。我需要它更快,因为有数百万次迭代。据我所知,目前无法并行化,因为我使用的唯一 for 循环取决于之前的迭代,这不允许并行化。正确的?如果并行化是不可能的,那么如何优化它以使其变得更快。我很惊讶,因为这只比我原来的 python 代码快 运行s 3 倍。 (有人说 C++ 比 python 快 100 到 400 倍)
如果需要VisualStudio 2015项目文件,请告诉我..
如果您运行申请:
您需要输入一个 sha1 哈希,然后告诉程序基本单词有多少个字符,例如单词测试:
哈希:a94a8fe5ccb19ba61c4c0873d391e987982fbbd3
长度:4
谢谢指教
#include "stdafx.h"
#include <stdio.h>
#include <string>
#include <iostream>
#include <cstring>
#include "..\crytoPP\sha.h"
#include "..\crytoPP\filters.h"
#include "..\crytoPP\hex.h"
#include "..\crytoPP\channels.h"
using namespace CryptoPP;
using namespace std;
int found = 0;
int iteration = 0;
int length;
char source[] = "abcdefghijklmnopqrstuvwxyz";
string solution = " didn't match";
string base_hash;
string CHECK(string hash, int argc, char** argv);
void COMBINATIONS(string b, int length, int source_length, int argc, char** argv);
int main(int argc, char** argv)
{
char *arr_ptr = &source[0];
int source_length = strlen(arr_ptr);
cout << "Please enter hash:";
cin >> base_hash;
cout << "Please enter length:";
cin >> length;
transform(base_hash.begin(), base_hash.end(), base_hash.begin(), ::toupper);
COMBINATIONS("", ::length, source_length, argc - 1, argv + 1);
system("PAUSE");
return 0;
}
string CHECK(string hash, int argc, char** argv) {
if (::found == 0) {
iteration++;
cout << iteration << endl;
if (argc == 2 && argv[1] != NULL)
hash = string(argv[1]);
string s1;
SHA1 sha1; SHA224 sha224; SHA256 sha256; SHA512 sha512;
HashFilter f1(sha1, new HexEncoder(new StringSink(s1)));
ChannelSwitch cs;
cs.AddDefaultRoute(f1);
StringSource ss(hash, true /*pumpAll*/, new Redirector(cs));
cout << s1 << endl;
if (s1 == ::base_hash) {
::found = 1;
cout << " =" << hash << endl;
}
return s1;
}
}
void COMBINATIONS(string b, int length, int source_length, int argc, char** argv) {
if (::found == 0) {
if (length == 0) {
CHECK(b, argc, argv);
}
else {
for (int i = 0; i < source_length; i++) {
COMBINATIONS(b + ::source[i], length -1, source_length, argc -1, argv + 1 );
CHECK(b, argc - 1, argv + 1);
}
}
}
}
您应该尝试的第一件事是在每次迭代中删除输出,因为这会显着降低程序的性能。
现在您只使用一个空字符串 b
调用 COMBINATIONS
一次,但是如果您要为 [=13] 中大小为 1 的每个起始字符串 b
创建一个线程=] 你可以有例如26 个线程,每个线程解决同样大小的问题部分。然而,最好的办法是尝试重写 COMBINATIONS
函数以更好地适应并行性。
此外,您目前每次调用 CHECK
时都会泄漏内存,这现在看起来可能不是什么大问题,但是您要查找的单词越长,您的程序需要的内存就越多。 C++ 要求您自己管理内存,因此您至少应该通过使用 delete
释放您使用 new
分配的所有内存(以确保它可以被重用)。如果您尝试重用您创建的那些对象,那就更好了,因为内存分配也有点慢。
最后但同样重要的是,请重新考虑 incrementing/decrementing argc
和 argv
的目的。坦率地说,我不太明白你的意图,这似乎是邪恶的。
我是 C++ 的新手(实际上才两天),我想知道是否可以使用此代码进行一些并行化。我需要它更快,因为有数百万次迭代。据我所知,目前无法并行化,因为我使用的唯一 for 循环取决于之前的迭代,这不允许并行化。正确的?如果并行化是不可能的,那么如何优化它以使其变得更快。我很惊讶,因为这只比我原来的 python 代码快 运行s 3 倍。 (有人说 C++ 比 python 快 100 到 400 倍)
如果需要VisualStudio 2015项目文件,请告诉我..
如果您运行申请: 您需要输入一个 sha1 哈希,然后告诉程序基本单词有多少个字符,例如单词测试: 哈希:a94a8fe5ccb19ba61c4c0873d391e987982fbbd3 长度:4
谢谢指教
#include "stdafx.h"
#include <stdio.h>
#include <string>
#include <iostream>
#include <cstring>
#include "..\crytoPP\sha.h"
#include "..\crytoPP\filters.h"
#include "..\crytoPP\hex.h"
#include "..\crytoPP\channels.h"
using namespace CryptoPP;
using namespace std;
int found = 0;
int iteration = 0;
int length;
char source[] = "abcdefghijklmnopqrstuvwxyz";
string solution = " didn't match";
string base_hash;
string CHECK(string hash, int argc, char** argv);
void COMBINATIONS(string b, int length, int source_length, int argc, char** argv);
int main(int argc, char** argv)
{
char *arr_ptr = &source[0];
int source_length = strlen(arr_ptr);
cout << "Please enter hash:";
cin >> base_hash;
cout << "Please enter length:";
cin >> length;
transform(base_hash.begin(), base_hash.end(), base_hash.begin(), ::toupper);
COMBINATIONS("", ::length, source_length, argc - 1, argv + 1);
system("PAUSE");
return 0;
}
string CHECK(string hash, int argc, char** argv) {
if (::found == 0) {
iteration++;
cout << iteration << endl;
if (argc == 2 && argv[1] != NULL)
hash = string(argv[1]);
string s1;
SHA1 sha1; SHA224 sha224; SHA256 sha256; SHA512 sha512;
HashFilter f1(sha1, new HexEncoder(new StringSink(s1)));
ChannelSwitch cs;
cs.AddDefaultRoute(f1);
StringSource ss(hash, true /*pumpAll*/, new Redirector(cs));
cout << s1 << endl;
if (s1 == ::base_hash) {
::found = 1;
cout << " =" << hash << endl;
}
return s1;
}
}
void COMBINATIONS(string b, int length, int source_length, int argc, char** argv) {
if (::found == 0) {
if (length == 0) {
CHECK(b, argc, argv);
}
else {
for (int i = 0; i < source_length; i++) {
COMBINATIONS(b + ::source[i], length -1, source_length, argc -1, argv + 1 );
CHECK(b, argc - 1, argv + 1);
}
}
}
}
您应该尝试的第一件事是在每次迭代中删除输出,因为这会显着降低程序的性能。
现在您只使用一个空字符串 b
调用 COMBINATIONS
一次,但是如果您要为 [=13] 中大小为 1 的每个起始字符串 b
创建一个线程=] 你可以有例如26 个线程,每个线程解决同样大小的问题部分。然而,最好的办法是尝试重写 COMBINATIONS
函数以更好地适应并行性。
此外,您目前每次调用 CHECK
时都会泄漏内存,这现在看起来可能不是什么大问题,但是您要查找的单词越长,您的程序需要的内存就越多。 C++ 要求您自己管理内存,因此您至少应该通过使用 delete
释放您使用 new
分配的所有内存(以确保它可以被重用)。如果您尝试重用您创建的那些对象,那就更好了,因为内存分配也有点慢。
最后但同样重要的是,请重新考虑 incrementing/decrementing argc
和 argv
的目的。坦率地说,我不太明白你的意图,这似乎是邪恶的。