GPU accelerated recursive function in C++ - c++

I'm quite new to C++(two days actually) and I would like to know if it is possible to do some parallelization with this code. I need this to be a hell lot faster as there are millions of iterations. From what I've understood so far it is not possible to parallelize, as the only for loop I use depends on the iteration before, which doesn't allow parallelization. Right? And if parallelization is not possible, how to optimize it otherwise so it gets faster. I was quite surprised as this only runs 3x faster than my original python code. (some said C++ is up to 100 to 400x faster than python)
If the VisualStudio 2015 project files are needed, please tell me..
If you run the application:
You need to enter a sha1 hash and then tell the programm how many characters the base word had, so for example the word test:
hash: a94a8fe5ccb19ba61c4c0873d391e987982fbbd3
length: 4
Thanks in advice
#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);
}
}
}
}

The first thing you should try is to remove your output in every iteration as this does significantly reduce the performance of your program.
Right now you are invoking COMBINATIONS only once with an empty string b, but if you would create one thread for every starting string b of size 1 in main you can have e.g. 26 threads each solving an equally sized part of the problem. Yet, best would be to try to rewrite the COMBINATIONS function to be better suited for parallelism.
Moreover you are currently leaking memory every time you call CHECK which right now might not seem as much as a problem, however the longer the word you are looking for, the more memory your program will require. C++ requires you to manage the memory yourself, so you should at least free all the memory you allocated with new by using delete (to make sure it can be reused). Even better if you would try to reuse those objects you created as memory allocations are somewhat slow as well.
Last but not least please rethink the purpose of incrementing/decrementing argc and argv. Frankly I do not quite understand your intention there and it seems evil.

Related

C++ Comparing argv[1] with a char of the same value always returns False

I am writing a simple program that compares a single character from argv[] to a character in a char array. This is done using a for loop to check if argv[1] is any of the characters in the character array, which is to serve as an input error check.
What I have done to implement this is below:
#include <iostream>
using namespace std;
int main(int argc, char* argv[])
{
const char validCharacters[] = "abcde01234";
int goodChars = 0;
for (int i = 0; i < sizeof(validCharacters) - 1; i++) {
if (strcmp(argv[1], &validCharacters[i]) == 0) {
cout << "Characters match!" << endl;
goodChars++;
}
}
if (goodChars > 0) {
cout << "Input OK!";
}
else {
cout << "Invalid input!";
}
return 0;
}
I inputted '0' as the value for argv[].
When I was debugging, this, I found that strcmp(argv[1], &validCharacters[i]) returns -1, and that sizeof(argv[1]) returns 4.
Why is it that argv[1] has the size of 4 despite only having '0' entered into it?
I'm certain that this is the reason why my program isn't working and would like to know if there is a way to resolve this problem.
Also, I'm not very experienced in C++, so anything you thing is bad practice, please let me know.
argv is an array of char pointers. In order to compare and get the size of the actual value, you'll have to dereference the char object.
For example, to get the size:
if(*argv[1] == '0'){
// Do Something
}
Checks if the first argument(argv[0] is the command itself), is equal to the character '0'. Here I dereference the char at index 1 of the argv array.

Why is this code not affecting the output?

This is supposed to take the input and move each letter 1 to the right. Is the pause stopping it from doing anything?
How can I change it so that it doesn't just output what the user inputs?
This is the code in C++ in Visual Studio Community 2013:
#include "stdafx.h"
#include <iostream>
using namespace std;
#include <string>
#include <cctype>
int _tmain(int argc, _TCHAR* argv[])
{
string cyphertext;
cout << "Paste your cyphertext and press enter to shift right 1: ";
cin >> cyphertext;
void encrypt(char * cyphertext, unsigned int offset);
for (int i = 0; cyphertext[i] != 0; i++) {
char firstLetter = islower(cyphertext[i]) ? 'a' : 'A';
unsigned int alphaOffset = cyphertext[i] - firstLetter;
int offset = 0;
unsigned int newAlphaOffset = alphaOffset + offset;
cyphertext[i] = firstLetter + newAlphaOffset % 26;
cout << "" << "Right One: " << cyphertext;
system("pause");
return 0;
}
}
Your pause is inside the 'encrypting' loop. It needs to be outside. The return in the loop will terminate the program; that too needs to be outside the loop.
Note that it is easier to see such mistakes when the code is indented in an orthodox layout such as the one now in the question. Working with scratty layouts makes it really hard to see many problems that are obvious when the code is tidily laid out.
You also declare a function encrypt() which you never use; don't do that. And it's generally a bad idea to declare functions inside other functions. And given that there isn't an encrypt() function defined, there isn't a 'void function', so I've changed the question title for you.

Why is my command line argument handling crashing my program?

Why is something so seemingly simple is crashing my program?
I am trying to get a value for n to make an array the size of N and perform various operations on it, but that's beside the point. Anyways, It keeps crashing every time I try to access argv[1].
int main(int argc, char * argv[])
{
int n;
n = atoi(argv[1]); //Crashes here!
cout << "\nN: " << n << endl;
}
Does argv[1] exist? To prevent your code from accessing memory it should not check how many arguments were passed.
if(argc >= 2)
n = argv[1];
else
std::cout << "Proper usage: .....\n";
This seems like a great time to learn how to use your debugger to view the contents of argv and argc.

c++ count down script

#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
int num, num2;
num = 33;
do
{
cout <<"\n" <<num-3;
}
while (num >=3);
system("PAUSE");
return EXIT_SUCCESS;
}
I have coded the above but when I run it, it outputs 30 and does not deplete the value to 3.
How can I have the loop do this? I know that num-- would work but that would only deplete the value by one. I'm new to c++ and I am trying to figure these things out.
Thanks! :)
//edit thanks I have it working now with num = num - 3, num-=3 works too
this line:
cout <<"\n" <<num-3;
does not change the value of num. It just outputs the value of num - 3. To actually change the value you need another line, such as:
num -= 3;
Even if you do as suggested and subtract 3 (or whatever) every iteration of your loop, it may not do a whole lot of good. The problem is fairly simple: you're likely updating your variable a lot faster than the output can be printed, so you may easily see a dozen or more values all appear at essentially the same time.
To cure that, you generally want to pause for a short time between iterations, so one value will (probably) be visible before the next is printed. Based on the system("pause");, I'm going to guess you're running Windows, in which case code something like this may be a bit more to your liking:
#include <cstdlib>
#include <iostream>
#include <windows.h>
using namespace std;
int main(int argc, char *argv[])
{
int num = 33;
do
{
cout <<" \r" << (num-=3);
Sleep(100);
}
while (num >=3);
return EXIT_SUCCESS;
}

integer arguments for c++

I have a sort of calculator in C++ that should accept arguments when executed. However, when I enter 7 as an argument, it might come out to be 10354 when put into a variable. Here is my code:
#include "stdafx.h"
#include <iostream>
int main(int argc, int argv[])
{
using namespace std;
int a;
int b;
if(argc==3){
a=argv[1];
b=argv[2];
}
else{
cout << "Please enter a number:";
cin >> a;
cout << "Please enter another number:";
cin >> b;
}
cout << "Addition:" << a+b << endl;
cout << "Subtaction:" << a-b << endl;
cout << "Multiplycation:" << a*b << endl;
cout << "Division:" << static_cast<long double>(a)/b << endl;
system("pause");
return 0;
}
Wherever did you get int argv[]? The second argument to main is char* argv[].
You can convert these command line arguments from string to integer using strtol or to floating-point using strtod.
For example:
a=strtol(argv[1], nullptr, 0);
b=strtol(argv[2], nullptr, 0);
But you can't just change the parameter type, because the operating system is going to give you your command-line arguments in string form whether you like it or not.
NOTE: You must #include <stdlib.h> (or #include <cstdlib> and using std::strtol;) to use the strtol function.
If you want error-checking, use strtol instead of atoi. Using it is almost as easy, and it also gives you a pointer to the location in the string where parsing terminated. If that points to the terminating NUL, parsing was successful. And of course it is good that you verify argc to make sure the user provided enough parameters, and avoid trying to read missing parameters from argv.
Example of error checking:
char* endp;
a = strtol(argv[1], &endp, 0);
if (endp == argv[1] || *endp) { /* failed, handle error */ }
The function signature is int main(int argc, char *argv[]). argv is an array of string pointers.
If the argument is 7, it will be in the form of a string ("7"). Use atoi() to convert it to the number 7.
Second argument in the main should either either be char* argv[] or char** argv. Then you have to have convert them to int.