|
I've got some weird performance in a sine approximation for a project that's eating me and one of my research partners. The code looks likecode:
|
# ? Jul 22, 2011 19:57 |
|
|
# ? Jun 8, 2024 01:41 |
|
Otto Skorzeny posted:I feel that the only way this could be possible is if I'm running into register pressure and spilling poo poo onto the stack or something, but I can't see where that would be. Any ideas? Maybe you're running into CPU floating point multiplier pressure. Edit: With optimization off I get <2x worse performance (than the first version) with the second approximation uncommented. Edit: With optimization set to maximum speed I get similar results, a 1.8x difference between the two versions. This is with an i7-2820QM cpu. Edit: And the second version runs 3x faster than the system sin. shrughes fucked around with this message at 22:22 on Jul 22, 2011 |
# ? Jul 22, 2011 22:06 |
|
Could it be that with the longer function, the compiler is deciding not to inline it? (Alternatively, if just slicing off a multiply makes it fast for whatever mysterious reason, can you change the last line to "return (scale * fabsf(f) + iscale) * f;"?)
|
# ? Jul 24, 2011 16:11 |
|
Could you be getting denormalized values? It looks like this would only happen for pretty small theta though. You could try unmasking the FPU's denormal exceptions, so you get an exception if it hits a denormal, or if this is generating SSE instructions, you could set the FTZ and DAZ bits for SSE. Which is the multiply that you remove to speed things up, or does removing any multiply work? Can you use a performance profiling tool (there's VTune on Windows, and Instruments on OS X is really great), to see what instructions are slowing you down?
|
# ? Jul 24, 2011 18:00 |
|
Does the domain that you are testing on include numbers near the roots? It could be that the first approximation is returning denormal numbers for numbers near pi and zero and the second one is doing arithmetic on them, which would be extremely slow.
|
# ? Jul 25, 2011 00:17 |
|
C++ question! I have an assignment in which I have to grab some numbers from a .dat file and bring them into my C++ program, then work with them in there as integers. I know how to bring them in, but I don't know how to convert them from characters to integers (because the .get function only takes character values correct?). Please help my terrible self.
|
# ? Jul 26, 2011 04:36 |
|
Good Will Punting posted:C++ question! What does this dat file look like? Can you post a sample? If it's just a bunch of numbers separated by whitespace, then you can just cin >> number where number is an integer capable of holding the ranges of the numbers.
|
# ? Jul 26, 2011 04:59 |
|
Yeah it's just a series of numbers separated by white spaces. I'll try that, thanks. Do I have to cast them or anything so I'll get the actual number values to use for calculations and not their ASCII values?
|
# ? Jul 26, 2011 05:02 |
When you use the C++ streams i/o to input and output integers from a text stream (such as a text file) it automatically converts behind the scenes. But apart from that, writing your own functions to convert between strings and integers is a good exercise.
|
|
# ? Jul 26, 2011 05:08 |
|
I should have been more detailed, my fault. I have 12345 in a .dat file. I need to create an array with a[0]= 1, a[1] = 2, a[2] = 3, a[3] = 4, a[4] = 5. I was under the impression that to input character by character I would need to use a .get function, which (if I'm not mistaken) requires a character argument. Sorry for leaving those not so minor details out. I'm exhausted and way too new at this to be making a fool out of myself on the internet.
|
# ? Jul 26, 2011 05:19 |
Okay so single digit numbers with no separation. Well, characters are just numbers. In ASCII (and Unicode), capital 'A' has the value 65, 'B' has the value 66, etc., and numeral '0' has value 48. But the actual values usually aren't that relevant, since C (and C++) has lets you enter character literals and treat them as numbers. code:
Knowing that order of the numerals, you can do a little arithmetic: If you subtract the character code for '0' from the character code of a character you know to be a numeral, you will get the numerical value. '0'-'0' is 0, '1'-'0' is 1, '2'-'0' is 2, and so on. Of course, if you don't know whether your input is all numbers, you need to check each character you read for being in range. But remember, there are just numbers. Characters and text are a convenient illusion! Things get much more complicated if you want to work with Unicode properly, and any software that will have be used by more people than just yourself needs to.
|
|
# ? Jul 26, 2011 06:03 |
|
nielsm posted:This assumes that the numerals 0, 1, 2, ..., 9 are laid out in that order in the character set, but they are on any machine your software will end up running on This is actually required by the C standard.
|
# ? Jul 26, 2011 06:24 |
|
A simple optimization/best practice question. When reading input of unknown length from stdin (could be typed in or piped, or modified to read from a file), is it better to stuff the input into a linked list of my items, or directly into an array which would be reallocated for each (or each n) items? In my case an array is much more useful for random access, so I read the data into a linked list first, and when the end is reached, copy it itno an array. I'm sure it's a case of premature optimization (if my approach is not counterproductive, that is) since the input lenght should be quite small, but I'm curious what's the "correct" approach, if there is one. PS. That's with plain C.
|
# ? Jul 26, 2011 13:56 |
|
One thing you can do is double the size of the array each time it gets filled up. This way you get constant time appending, and the memory wasted is at most 50%
|
# ? Jul 26, 2011 14:07 |
|
if you know ahead of time that the input is going to be short, and memory isn't horribly constrained, just use a sufficiently large fixed size array.
|
# ? Jul 26, 2011 14:59 |
tractor fanatic posted:One thing you can do is double the size of the array each time it gets filled up. This way you get constant time appending, and the memory wasted is at most 50% If you mean re-allocate the array, remember that it might easily involve a copy of all the items from the previous location to the new. mobby's own suggestion of having a linked list kind of structure, just making a new allocation every time, is likely to be faster, if he's working with unbounded input. Of course, if you know for sure that no sensible input is longer than, say, 512 bytes, just allocate that and ignore anything further. Remember to not blow your buffers
|
|
# ? Jul 26, 2011 18:41 |
|
nielsm posted:If you mean re-allocate the array, remember that it might easily involve a copy of all the items from the previous location to the new. The array method is better than it sounds. On average, you'll be copying each byte probably about once, and definitely less than twice, compared to the linked list method where you copy each byte once. There's probably not much difference between the two approaches. (In any case, if the input is typed or from a file, both approaches will have pretty small impact compared to the time spent reading the input into the program)
|
# ? Jul 26, 2011 19:04 |
|
Thanks to everyone who helped with the sin() stuff, it did turn out to be an artifact of the code I was using to time it introducing denormals way more often than expected
|
# ? Jul 26, 2011 19:35 |
|
Qwertycoatl posted:The array method is better than it sounds. On average, you'll be copying each byte probably about once, and definitely less than twice, compared to the linked list method where you copy each byte once. There's probably not much difference between the two approaches. The way I like to do this sort of thing is to make a hugely oversized array on the stack that I read the data into, then allocate the real permanent array once I know how big it needs to be, and copy it across - total overhead, one copy, no memory wasted. The limitation, of course, being the assumption that the selected "hugely oversized" will always be enough room for future versions of the data. If that's a concern you can combine it with the "double the array when you overflow" method, using the big stack to read onto then appending to the "real" array either when your stack array is full or the data ends - the advantage there being that you don't end up with the up to 50% wasted memory staying allocated, but the disadvantage that you may end up, in the unlikely huge data situation, doing 10 re-allocates where the doubling method would only do 3. Another alternative you could do is to do the array doubling method followed by a final re-allocate of the final actual data size, to remove any wasted allocation (at the cost of one more copy).
|
# ? Jul 26, 2011 19:55 |
|
nielsm posted:If you mean re-allocate the array, remember that it might easily involve a copy of all the items from the previous location to the new. You can easily get amortized constant time appends to an array even if you recopy the whole thing on every reallocation.
|
# ? Jul 27, 2011 02:16 |
|
Hey guys I am doing an assignment for my CompSci course. It is my first time using C++, I have very little C knowledge also so please don't be too harsh. I was going along fine until I changed something in the for loop and now my program crashes on startup with a SIGSEGV error. I can pretty much comment out all the code and it still happens so it's really confusing me. What is causing it? code:
|
# ? Jul 27, 2011 05:26 |
|
"Pretty much" comment out all the code? What happens if you change main to this?: code:
|
# ? Jul 27, 2011 05:38 |
|
current has length MAXSIZE, so the valid indexes into it go from 0 to MAXSIZE-1, so returning current[MAXSIZE] is actually guaranteed to not work. The "wonderful" thing about C++ is that doing it anyway just gives you crashes and/or garbage data instead of some more intelligible error. Anyway, stepping back for a second, the problem is that you seem to think that return current[MAXSIZE]; returns the entire array or something. It doesn't. You need to be thinking more carefully about where your objects are stored.
|
# ? Jul 27, 2011 05:45 |
|
rjmccall posted:current has length MAXSIZE, so the valid indexes into it go from 0 to MAXSIZE-1, so returning current[MAXSIZE] is actually guaranteed to not work. The "wonderful" thing about C++ is that doing it anyway just gives you crashes and/or garbage data instead of some more intelligible error. Thanks for your responses. I seem to have reoccurring difficulty with arrays and loops, I had similar difficulties with a course I did last semester with Java. I would like to attribute my difficulty with this down to the fact that it's all new but arrays and loops are fairly common structures no matter what the language. Do you know of any resources that I learn from to get my logic up to speed? My aim with return current[MAXSIZE]; was that I am not allowed to use global variables and I need the display() and process() functions to access that information. I'm not very familiar with how C++ does this kind of thing. How would I go about this? Also the choice of MAXSIZE isn't perfect either in that it would be better if it could determine when the a1in.txt file ended and make the array that big, rather than a pre-determined size.
|
# ? Jul 27, 2011 06:44 |
Have you covered any of the standard container classes, such as std::vector in class? Because that's basically what you want to use, std::vector is an automatically expanding dynamic array. If you haven't, "cheat" and look through your book, it should be covered relatively soon if it's a C++ book worth anything.
|
|
# ? Jul 27, 2011 06:50 |
|
Red_Fred posted:My aim with return current[MAXSIZE]; was that I am not allowed to use global variables and I need the display() and process() functions to access that information. I'm not very familiar with how C++ does this kind of thing. How would I go about this? Well, let's work this out. There are three places you can allocate objects:
You need the lifetime of the storage to overlap all of your operations. You've been forbidden from using static storage. So you can either use local storage, in which case you'll need to declare it in a scope which survives across all of your operations, or you can use dynamic storage. In both solutions you'll have to pass pointers or references around. Red_Fred posted:Also the choice of MAXSIZE isn't perfect either in that it would be better if it could determine when the a1in.txt file ended and make the array that big, rather than a pre-determined size. Well, that's not impossible: just make two passes over the file, counting the number of entries on the first pass and filling in the array on the second. Since the number of entries isn't constant, you'd have to use dynamic storage. An alternative would be to use a data structure which grows as you find new entries. You could use static or local storage, but it's better to use dynamic storage, or else the data structure won't be able to grow past a constant size. For example, you could dynamically allocate an array and reallocate it whenever it needs to grow, copying all the old data before deleting the old allocation. This is essentially what the standard data structures like std::vector do, except they're much smarter about it.
|
# ? Jul 27, 2011 08:44 |
|
The array method looks much better now thanks to all the suggestions, although the linked list seemed like such a great idea to avoid copying and reallocating stuff in my head . I'll leave the existing code as is, since it doesn't really make a difference either way, but keep this in mind for future.
|
# ? Jul 27, 2011 09:09 |
|
nielsm posted:Have you covered any of the standard container classes, such as std::vector in class? Because that's basically what you want to use, std::vector is an automatically expanding dynamic array. If you haven't, "cheat" and look through your book, it should be covered relatively soon if it's a C++ book worth anything. No unfortunately we haven't and we have been told explicitly not to use features that have not been taught yet. rjmccall posted:Well, let's work this out. There are three places you can allocate objects: We haven't been taught pointers and have been told not to use them. So I guess that leaves references which are like &e right? We can use new and delete however also we were told that there would never be more than 100 entries that are tested, hence MAXSIZE. However there could be any number from 1-100. Thanks a lot for your help. I'm going to get back to it tomorrow morning and hopefully I will be posting back successes.
|
# ? Jul 27, 2011 09:32 |
Red_Fred posted:We haven't been taught pointers and have been told not to use them. Red_Fred posted:We can use new and delete however What. You basically can't use new and delete without using pointers. (You can "cheat" and make references of your pointers, but there isn't much point to that.) My suggestion to what you should do: Declare the array for the entries in your main function, then pass a reference to it into all functions that need to work on it. I.e. you tell the reading function, "put the data you read into this array", rather than having it return a new array. The reading function should then either return void (i.e. nothing), or maybe better, an int telling how many entries were actually read. As general advice, when working with raw arrays and passing them as parameters to functions, it's a good idea to make sure the function called knows how many elements are allocated and how many of those are valid.
|
|
# ? Jul 27, 2011 14:16 |
|
More specifically to nielsm's spoiler - the general method used is to pass in an array (which is actually a pointer to an array, but your teacher probably didn't mean you can't use *that* sort of pointer) and the length of the array (which the function must not exceed). The function then fills the array as much as there is data available, or to capacity, whichever comes first, and returns the number of elements it filled - this way you can print out n elements in your output rather than MAX_ELEMENTS elements. That's the system used by many of the Windows API functions and standard library string functions such as fgets (though many of the string ones don't return a length because you can use strlen for that). Speaking of which, that's an option for you too - you could set some "end of array" value rather than passing a length around, provided there is some value that you know won't ever occur (eg. you could use -1 if you know the data is all positive integers.) But if you do that you need to remember that your maximum array length is effectively one less, because you need to have room for the end-tag. Edit: and yeah, "you can't use pointers but you can use new and delete" means "either the teacher is an idiot or you misunderstood something." Perhaps he just meant you shouldn't be iterating pointers. roomforthetuna fucked around with this message at 17:28 on Jul 27, 2011 |
# ? Jul 27, 2011 17:22 |
|
Does anyone have any thoughts on using Microsoft's new Concurrency runtime versus, say, boost::thread? We're already pretty locked into MS so portability isn't an issue.
|
# ? Jul 27, 2011 23:07 |
|
GrumpyDoctor posted:Does anyone have any thoughts on using Microsoft's new Concurrency runtime versus, say, boost::thread? We're already pretty locked into MS so portability isn't an issue. And boost thread does some weird poo poo with TLS or some such which makes the resulting executable sufficiently non-standard that executable compression programs don't work properly on it. Unless you put this into one of your project's files, which fixes that but probably breaks something else. code:
|
# ? Jul 27, 2011 23:43 |
|
nielsm posted:What. roomforthetuna posted:More specifically to nielsm's spoiler - the general method used is to pass in an array (which is actually a pointer to an array, but your teacher probably didn't mean you can't use *that* sort of pointer) and the length of the array (which the function must not exceed). The function then fills the array as much as there is data available, or to capacity, whichever comes first, and returns the number of elements it filled - this way you can print out n elements in your output rather than MAX_ELEMENTS elements. That's the system used by many of the Windows API functions and standard library string functions such as fgets (though many of the string ones don't return a length because you can use strlen for that). Speaking of which, that's an option for you too - you could set some "end of array" value rather than passing a length around, provided there is some value that you know won't ever occur (eg. you could use -1 if you know the data is all positive integers.) But if you do that you need to remember that your maximum array length is effectively one less, because you need to have room for the end-tag. When I first posted here I sent an email to my lecturer to see if she could steer me in the right direction and she sent me one of the previous year's questions and solutions which was kind of similar. From that and your suggestions here I managed to almost finish it. Turns out I pretty much did what you said above nielsm, I really need to print that in to my brain that you use a separate size variable when working with arrays of unknown size. I still find it a bit confusing with regard to what is actually happening with references and all but the program works. As far as the pointer thing goes that would most likely be me getting things mixed up, although she did say no pointers and new and delete are in our notes so far. I think she was talking about *p type pointers if that makes more sense. This is my process function which was working fine until I put in int count to count the number of entries read. Now it always says 0 read even when there should be some. The values upper, lower I have tested and they are taking the data as they should. Seems my if is wrong somehow. Ideas? code:
|
# ? Jul 27, 2011 23:47 |
|
Red_Fred posted:although she did say no pointers and new and delete are in our notes so far. I think she was talking about *p type pointers if that makes more sense. new returns a pointer, so you'd have to at the very least declare a pointer as a variable or as a function parameter, to usefully use new. quote:question about the function
|
# ? Jul 28, 2011 00:04 |
|
Yeah the display function is fine as it is called earlier and works. Also size is fine as I put it the cout before the for loop and it displays 4, which it should. To me it seems like the if statement isn't being used, why I don't know though as it was working fine before I put int count in.
|
# ? Jul 28, 2011 00:25 |
|
roomforthetuna posted:If you haven't already installed boost for something else, and don't intend to use it for anything else, I recommend not using boost (having just spent 3 days getting it and libtorrent-rasterbar to install properly and play well together). The install procedure for boost in Windows has apparently changed completely at least three times between version 1_34_0 and 1_47_0 (or whatever it is now) and the install documentation frequently doesn't say which version it's for. Adding boost stuff to your #includes makes compilation take significantly longer, and linking against boost libraries is also a remarkable slowdown. Oh I am plenty familiar with boost - the current project not only uses boost, but a nuclear-powered generic computational geometry library built on top of boost. I had to manually increase the heap allocation for generating the .pch three times, I regularly get that warning about decorated names being truncated, and a full build (without optimizations) still takes a good ten minutes for less than 10k lines of my own code. So yeah, I guess the fact that we're already using boost should factor into this somehow.
|
# ? Jul 28, 2011 00:58 |
|
Red_Fred posted:This is my process function which was working fine until I put in int count to count the number of entries read. Now it always says 0 read even when there should be some. The values upper, lower I have tested and they are taking the data as they should. Seems my if is wrong somehow. Ideas? Usually I assume that lower bounds are lower than upper bounds, but I guess you can name your variables whatever you want.
|
# ? Jul 28, 2011 01:42 |
|
rjmccall posted:Usually I assume that lower bounds are lower than upper bounds, but I guess you can name your variables whatever you want. do I feel silly. Thanks!
|
# ? Jul 28, 2011 01:54 |
|
Okay, I'm going to be taking a class in C. (Mostly because in order to take C++, the particular class prerequisites are taking the C class, though I think I saw the book used by the class [going by id number] being a C++ book. Haven't got the name of the actual book going to be used yet, though.) I'm wondering, are the books listed in the OP still the go-to ones for learning/refreshing on C/C++, or if opinions have changed since the OP was last edited. Additionally, are there any other important resources I should look at? I did see a link to Google's C++ style guide, that I will look at.
|
# ? Jul 28, 2011 02:55 |
|
|
# ? Jun 8, 2024 01:41 |
|
roomforthetuna posted:That said, don't listen to me Good advice. Boost is pretty awesome and you're really completely overlooking how modular it is. Any issues you have with particular libraries is a problem with those particular libraries, not with boost as a whole.
|
# ? Jul 28, 2011 03:05 |