This is the home of NCPrime software, providing free and open-source programs relating to prime numbers! It's also generally a blog about programming with the occasional rambling on number theory or discrete mathematics.
Tuesday, September 4, 2012
MuPuPriNT Roadmap
About time for this.
MuPuPriNT 1.2 will essentially be GJSieve 2.0 with buttons to select the type of number you wish to test as opposed to having to open an entirely different window.
Additionally, I think I may remove the box using Assembly code to retrieve and display your CPU and RAM. Formatting of this string is different on practically every machine I have tested - sometimes there are no spaces, and other times there are far too many! It was a nice idea. But, that space could be reclaimed and put to better use.
GJSieve 2.0 is still under development. I have some serious issues with thread management at the moment, so I must fix that up before I even consider expanding the already-huge project to include what is essentially (and have previously been) three separate applications.
MuPuPriNT 1.2 will essentially be GJSieve 2.0 with buttons to select the type of number you wish to test as opposed to having to open an entirely different window.
Additionally, I think I may remove the box using Assembly code to retrieve and display your CPU and RAM. Formatting of this string is different on practically every machine I have tested - sometimes there are no spaces, and other times there are far too many! It was a nice idea. But, that space could be reclaimed and put to better use.
GJSieve 2.0 is still under development. I have some serious issues with thread management at the moment, so I must fix that up before I even consider expanding the already-huge project to include what is essentially (and have previously been) three separate applications.
Monday, September 3, 2012
GJSieve 2.0 Calculations
I decided (about two hours ago) that GJSieve 2.0 was going to calculate the Proth number in a separate thread.
So, I implemented that. In retrospect, I don't really know why. Turns out that the reason GJSieve (for Windows, at least) took so long to "calculate" huge numbers was not due to the calculation at all - it was the printing of the number to the box!
So now, I am faced with a choice - find a way to incrementally print the calculated number to the box that does not involve a single giant string, or else severely limit the size of the numbers the user can test (rendering the application essentially useless).
Currently, if I were to calculate a number 3 million digits in length, it takes 0.003 seconds. However, the time taken to print it to the display box is seemingly (and inconveniently) infinite. I cannot quite tell if the thread is actually hanging or working (as CPU and memory usage remain quite high), but I'm willing to bet that writing a 3 million digit number to what is essentially an array with 3 million slots, followed by performing the necessary conversion to a wide-character array (also 3 million in length) is a generally terrible idea.
In C++, array length is virtually unlimited, yet physically highly limited. The first limit is obviously stack size, which I increased all the way to 25MB (which is admittedly small) before stopping to head off to work. I wasn't getting overflows...yet. The second limit is physically installed memory, of which I must rather hesitantly admit I have only 4GB - yes, even on my custom-built, highly optimized NCS Northwave machine.
The solution which first came to mind is using a vector to cycle through the number's digits and essentially print them one at a time, pushing and popping Assembly-style as necessary. This is not exactly possible, nor would it be much fun to write.
The other idea I had is to use gmp_snprintf() instead of mpz_get_str(). This should fill up, but not exceed, the buffer initialized with the size of the Proth number. sprintf() has no protection against this. Oops!
At any rate, I will have to try all that at some other time...
So, I implemented that. In retrospect, I don't really know why. Turns out that the reason GJSieve (for Windows, at least) took so long to "calculate" huge numbers was not due to the calculation at all - it was the printing of the number to the box!
So now, I am faced with a choice - find a way to incrementally print the calculated number to the box that does not involve a single giant string, or else severely limit the size of the numbers the user can test (rendering the application essentially useless).
Currently, if I were to calculate a number 3 million digits in length, it takes 0.003 seconds. However, the time taken to print it to the display box is seemingly (and inconveniently) infinite. I cannot quite tell if the thread is actually hanging or working (as CPU and memory usage remain quite high), but I'm willing to bet that writing a 3 million digit number to what is essentially an array with 3 million slots, followed by performing the necessary conversion to a wide-character array (also 3 million in length) is a generally terrible idea.
In C++, array length is virtually unlimited, yet physically highly limited. The first limit is obviously stack size, which I increased all the way to 25MB (which is admittedly small) before stopping to head off to work. I wasn't getting overflows...yet. The second limit is physically installed memory, of which I must rather hesitantly admit I have only 4GB - yes, even on my custom-built, highly optimized NCS Northwave machine.
The solution which first came to mind is using a vector to cycle through the number's digits and essentially print them one at a time, pushing and popping Assembly-style as necessary. This is not exactly possible, nor would it be much fun to write.
The other idea I had is to use gmp_snprintf() instead of mpz_get_str(). This should fill up, but not exceed, the buffer initialized with the size of the Proth number. sprintf() has no protection against this. Oops!
At any rate, I will have to try all that at some other time...
Thread Management Woes
I posted about this here...
The basic idea with the experimental six-thread testing method is to speed up the overall testing process. But how?
Well, I started on it last night when I randomly got the idea, and drew out a schematic whilst bored in class earlier today. I call it "Reverse," which is probably a bad name, but does describe what half of the threads do.
Threads 1, 2, and 3 each look for the first factor of the Proth number. Upon finding it, they test like this:
Threads 4, 5, and 6 don't care about the first factor, but they do care about the square root. They care a lot. They set the variable mpTrial to sqrt(Proth) and test like this:The basic idea with the experimental six-thread testing method is to speed up the overall testing process. But how?
Well, I started on it last night when I randomly got the idea, and drew out a schematic whilst bored in class earlier today. I call it "Reverse," which is probably a bad name, but does describe what half of the threads do.
Threads 1, 2, and 3 each look for the first factor of the Proth number. Upon finding it, they test like this:
- first factor + 1 up to sqrt(Proth)/2 with first factor += 3
- first factor + 2 up to sqrt(Proth)/2 with first factor += 3
- first factor + 3 up to sqrt(Proth)/2 with first factor += 3
- mpTrial -1 down to sqrt(Proth)/2 with mpTrial -= 3
- mpTrial -2 down to sqrt(Proth)/2 with mpTrial -= 3
- mpTrial -3 down to sqrt(Proth)/2 with mpTrial -= 3
However, it does not work properly. Not at all. In fact, it only does some of what it's meant to do. That's why I was posting about thread management (of the SAFE variety) and why GJSieve 2.0 is not available to download!
Naturally, now that I know how to multi-thread my application, I have found excuses to do it just about everywhere. Yet to come is a separate thread for calculating (as opposed to testing) the number, so that the application doesn't seize up when you tell it to calculate a million+ digit number. That ought not be too difficult.
More on GJSieve's crazy threading later.
Sunday, September 2, 2012
MuPuPriNT's Future
With GJSieve 2.0 being well on its way to "completion," I've taken another look at MuPuPriNT for Windows 1.1 and decided to scrap it.
Currently, it contains GJSieveP, GJSieveC, GJSieveW, and GJSievePy version 1.9.0 and IsItPrime version 1.5.6. Within the next week or so, I should be able to write GJSieveC, W, and Py versions 2.0 based on the triple-threaded testing method seen in GJSieve (Proth) version 2.0.
IsItPrime is currently on version 1.7.0 (which can be found on SourceForge).
MuPuPriNT for Mac, meanwhile, is terribly outdated, although multi-threading appears unnecessary at the moment.
In the near future, I will create a separate project for MuPuPriNT on SourceForge as well as subprojects for the various flavors of GJSieve.
The next release of MuPuPriNT will likely still be 1.1, although I will probably append a sub-release number.
The versioning of my applications may seem random and/or like the steps are too large. For instance, IsItPrime went from 1.5.6 to 1.6.0 to 1.7.0 in a matter of two weeks or so. But this makes sense. Major coding changes, coupled with overhauls of the graphical interface and overall changes to the way it actually tests numbers necessitated an increase in sub-version numbers.
Generally speaking, I name things 0.* if they are considered an alpha or testing release, meaning I am not entirely sure they do what I want or everything I want them to do in exactly the way I wish for them to do it.
Versions 1.* are considered stable betas at this point. That means they do everything they're meant to in a stable and efficient manner, although there are definitely still changes and things yet to be implemented.
GJSieve (Proth), where it all began, is on version 2.0 after months of development. It has a rich history of evolution, and I'm proud of the progress I've made even after becoming essentially the sole developer.
More on this later. For now, expect MuPuPriNT to become the focus of NCPrime projects for at least the foreseeable future. After all, what's the point of intensively developing and updating various standalones whilst their implementations in MuPuPriNT lag a version or two behind?
Here's an idea that literally just came to me.
Instead of a main "Chooser" window from which you select an application to run using boring buttons, imagine a window that simply looks like GJSieve 2.0, only with the addition of radio buttons or something to that effect labelled "Proth," "Cullen," "Woodall," "Pythagorean," and "Any number." Obviously "Any number" would be IsItPrime.
The trick is the entry box for k, as that is only used in the Proth number tester.
I suppose I could just have it become disabled upon selecting a test that is not Proth, but that could look a bit ugly. If it was easier (using the Win32 API) to simply hide and show things like edit controls and buttons, I would do it.
I will definitely look into that. MuPuPriNT for Mac will likely be where I'll prototype this unified implementation, so also be on the lookout for that!
Currently, it contains GJSieveP, GJSieveC, GJSieveW, and GJSievePy version 1.9.0 and IsItPrime version 1.5.6. Within the next week or so, I should be able to write GJSieveC, W, and Py versions 2.0 based on the triple-threaded testing method seen in GJSieve (Proth) version 2.0.
IsItPrime is currently on version 1.7.0 (which can be found on SourceForge).
MuPuPriNT for Mac, meanwhile, is terribly outdated, although multi-threading appears unnecessary at the moment.
In the near future, I will create a separate project for MuPuPriNT on SourceForge as well as subprojects for the various flavors of GJSieve.
The next release of MuPuPriNT will likely still be 1.1, although I will probably append a sub-release number.
The versioning of my applications may seem random and/or like the steps are too large. For instance, IsItPrime went from 1.5.6 to 1.6.0 to 1.7.0 in a matter of two weeks or so. But this makes sense. Major coding changes, coupled with overhauls of the graphical interface and overall changes to the way it actually tests numbers necessitated an increase in sub-version numbers.
Generally speaking, I name things 0.* if they are considered an alpha or testing release, meaning I am not entirely sure they do what I want or everything I want them to do in exactly the way I wish for them to do it.
Versions 1.* are considered stable betas at this point. That means they do everything they're meant to in a stable and efficient manner, although there are definitely still changes and things yet to be implemented.
GJSieve (Proth), where it all began, is on version 2.0 after months of development. It has a rich history of evolution, and I'm proud of the progress I've made even after becoming essentially the sole developer.
More on this later. For now, expect MuPuPriNT to become the focus of NCPrime projects for at least the foreseeable future. After all, what's the point of intensively developing and updating various standalones whilst their implementations in MuPuPriNT lag a version or two behind?
Here's an idea that literally just came to me.
Instead of a main "Chooser" window from which you select an application to run using boring buttons, imagine a window that simply looks like GJSieve 2.0, only with the addition of radio buttons or something to that effect labelled "Proth," "Cullen," "Woodall," "Pythagorean," and "Any number." Obviously "Any number" would be IsItPrime.
The trick is the entry box for k, as that is only used in the Proth number tester.
I suppose I could just have it become disabled upon selecting a test that is not Proth, but that could look a bit ugly. If it was easier (using the Win32 API) to simply hide and show things like edit controls and buttons, I would do it.
I will definitely look into that. MuPuPriNT for Mac will likely be where I'll prototype this unified implementation, so also be on the lookout for that!
Saturday, September 1, 2012
GJSieve 2.0 Progress Report
GJSieve 2.0 took only about a day to write!
Obviously, it is still in testing - but it seems to be working just fine. I was able to implement everything on the to-do list, too!
As you may well notice, there are indeed three testing threads, each of which now has their own message and display window. The boxes up on the top right have been changed around (and one deleted) to make things a bit easier to read and understand.
Perhaps most importantly, the PANIC button has been shrunk (though not deprecated) to make room for the Pause and STOP buttons. The Pause button will pause an in-progress test on all three threads, whilst the STOP button cancels the test outright and returns control to the main thread.
So, scenario time.
The test is running too long, but the application is responding and progress is being made - STOP
The test is running too long, and appears to be hanging and/or not responding - PANIC
You're bored of watching the test and/or need to give the CPU a break - Pause
Simple enough.
Additionally, the results files printed by the Save to File command are much more detailed and also better formatted.
Tweeting is new in GJSieve (for Windows anyway), although the implementation is exactly the same as IsItPrime's with the obvious change of tweeting the Proth number.
Tweets will not/cannot show results.
Technically speaking, in order to save a results file and/or post a Tweet from GJSieve 2.0, you need only enter k and n and press Calculate. You needn't have actually tested a number at all. However, the results file will show nothing at all, and I'm likely going to put in a check to make sure you aren't trying to save results for tests that were never performed!
One known issue arises with the "Show Proth Number" button. Currently, it shows a window that is populated upon pressing the "Calculate..." button. This is all well and good, except that you MUST click the button again (when it says "Hide Proth Number") rather than closing the window itself. For some reason, simply destroying the window sends mixed messages and leads to undefined behavior.
I can/will fix that - I'm just not entirely sure how.
I also have to make tooltips for every new thing here...
Additionally, a 64-bit version of GJSieve 2.0 is in the works. The biggest (and perhaps only) noticeable difference will be the absence of the CPU and RAM display bar, as 64-bit Windows API does not support inline assembly code (the _asm intrinsic). Oh well.
And now you know what I've done with my Saturday!
Obviously, it is still in testing - but it seems to be working just fine. I was able to implement everything on the to-do list, too!
As you may well notice, there are indeed three testing threads, each of which now has their own message and display window. The boxes up on the top right have been changed around (and one deleted) to make things a bit easier to read and understand.
Perhaps most importantly, the PANIC button has been shrunk (though not deprecated) to make room for the Pause and STOP buttons. The Pause button will pause an in-progress test on all three threads, whilst the STOP button cancels the test outright and returns control to the main thread.
So, scenario time.
The test is running too long, but the application is responding and progress is being made - STOP
The test is running too long, and appears to be hanging and/or not responding - PANIC
You're bored of watching the test and/or need to give the CPU a break - Pause
Simple enough.
Additionally, the results files printed by the Save to File command are much more detailed and also better formatted.
Tweeting is new in GJSieve (for Windows anyway), although the implementation is exactly the same as IsItPrime's with the obvious change of tweeting the Proth number.
Tweets will not/cannot show results.
Technically speaking, in order to save a results file and/or post a Tweet from GJSieve 2.0, you need only enter k and n and press Calculate. You needn't have actually tested a number at all. However, the results file will show nothing at all, and I'm likely going to put in a check to make sure you aren't trying to save results for tests that were never performed!
One known issue arises with the "Show Proth Number" button. Currently, it shows a window that is populated upon pressing the "Calculate..." button. This is all well and good, except that you MUST click the button again (when it says "Hide Proth Number") rather than closing the window itself. For some reason, simply destroying the window sends mixed messages and leads to undefined behavior.
I can/will fix that - I'm just not entirely sure how.
I also have to make tooltips for every new thing here...
Additionally, a 64-bit version of GJSieve 2.0 is in the works. The biggest (and perhaps only) noticeable difference will be the absence of the CPU and RAM display bar, as 64-bit Windows API does not support inline assembly code (the _asm intrinsic). Oh well.
And now you know what I've done with my Saturday!
GJSieve 2.0 To-Do
- optional window for showing Proth number
- triple-threaded testing as seen in IsItPrime
- calculation in another thread
- experiment with different thread management techniques
I am working on GJSieve 2.0, by the way.
Perhaps I will migrate it over to SourceForge...!
Subscribe to:
Posts (Atom)

