|
Contero posted:Is there some nanosleep or usleep equivalent in windows? Milliseconds are just slightly too coarse.
|
# ? Dec 12, 2008 04:12 |
|
|
# ? Jun 9, 2024 00:32 |
|
Lexical Unit posted:Earlier this year there was some discussion on the boost mailing list about timers which led me to this site. I was particularly impressed with the author's effort to document the pros and cons of all the available time devices his library can support. It looks like you might be able to use QueryPerformanceCounter() to get a high resolution timer, but it's dependent on your machine having a high resolution performance counter. I don't know if his library is any good as I haven't personally used it, but regardless, check out QueryPerformanceCounter() if you haven't already. Beyond that, I'm afraid I just don't know. I'm pretty sure most of that page is lies. QueryPerformanceCounter, by definition, measures wall time, so unless you have faulty hardware, CPU frequency scaling won't affect it.
|
# ? Dec 12, 2008 04:19 |
|
I thought QPC() measured counts by definition, and getting to wall time was a matter of discovering the frequency of those counts via QueryPerformanceFrequency(), no? Maybe he's saying that CPU frequency scaling affects QPF() (or possibly that it doesn't when it should). Regardless, after googling for a while I've gotten the impression that QPC() is rubbish for a lot of reasons, even if it is the Microsoft endorsed way of measuring nanosecond resolution time. Sucks.
|
# ? Dec 12, 2008 04:46 |
|
Pookdaddy G posted:Ok, so now i can actually see my full output. I noticed that i can find URL given the IP, but if given the URL i cannot find the IP. This leads me to think that my error is within Yes, you're looking in the right spot. No, you shouldn't change it to "if (differ != 7)", that's not the part that has a problem. You know that it's working for the IP lookups but not for the name lookups. So you should compare the two and see what you're doing differently (or, more to the point, what you're not doing differently), and you'll see what the problem is. Good luck!
|
# ? Dec 12, 2008 05:18 |
|
Olly the Otter posted:Yes, you're looking in the right spot. No, you shouldn't change it to "if (differ != 7)", that's not the part that has a problem. But when i change "the if (differ == 7)" back to that, then the file will get only to the "first process =" then cause a huge error. EDIT: Wait, nevermind, that was because of something else i changed. EDIT 2: I got it, i think... Please tell me that i was right in changing" differ = searchtable(IP, length, first);" to "differ = searchtable(URL, length, first);" Pookdaddy G fucked around with this message at 05:31 on Dec 12, 2008 |
# ? Dec 12, 2008 05:25 |
|
Pookdaddy G posted:But when i change "the if (differ == 7)" back to that, then the file will get only to the "first process =" then cause a huge error. That is correct.
|
# ? Dec 12, 2008 05:38 |
|
Olly the Otter posted:That is correct. gently caress yeah! Thanks so much man, you have probably just made my day, if not week.
|
# ? Dec 12, 2008 05:44 |
|
Lexical Unit posted:I thought QPC() measured counts by definition, and getting to wall time was a matter of discovering the frequency of those counts via QueryPerformanceFrequency(), no? Maybe he's saying that CPU frequency scaling affects QPF() (or possibly that it doesn't when it should). Regardless, after googling for a while I've gotten the impression that QPC() is rubbish for a lot of reasons, even if it is the Microsoft endorsed way of measuring nanosecond resolution time. Sucks. I don't see how it's crap, except that it has more overhead than some (but not all) other methods of measuring time. QueryPerformanceFrequency is required to return the same value each time for a given hardware configuration, and QueryPerformanceCounter is based on wall time. The only legitimate complaint I know of is that QPF/QPC doesn't work too well when dealing with buggy hardware/BIOSes. There's a lot of misinformation about QPC/QPF (I'm probably victim to some of it, myself!).
|
# ? Dec 12, 2008 06:16 |
|
Lexical Unit posted:Earlier this year there was some discussion on the boost mailing list about timers which led me to this site. I was particularly impressed with the author's effort to document the pros and cons of all the available time devices his library can support. It looks like you might be able to use QueryPerformanceCounter() to get a high resolution timer, but it's dependent on your machine having a high resolution performance counter. I don't know if his library is any good as I haven't personally used it, but regardless, check out QueryPerformanceCounter() if you haven't already. Beyond that, I'm afraid I just don't know. Well that's all well and good. I'm already using QPC for my timer, but I was asking about Sleep() calls. I'm just wondering if windows has a way of suspending the process/thread for an amount of time in chunks less than 1 millisecond. I'm really trying to figure out how I can get my little game to stay at a steady and reliable 60 frames per second. I originally thought I should do this by sleeping for exactly the time needed, but I'm starting to think that I should just sleep for 1 ms every time, and only draw when QPC says the last time I drew to the screen was more than 16.6 milliseconds ago.
|
# ? Dec 12, 2008 08:41 |
|
Sleep isn't a reliable way to do that anyway, since there's no guarantee that you will Sleep for precisely the length of time you request (usually it's a few ms more). What you want to do is to enable vertical sync through your API. I'm not really familiar with OpenGL, but in DirectX, you'd set D3DPRESENT_PARAMETERS::PresentationInterval to D3DPRESENT_INTERVAL_ONE. This has the effect of blocking all calls to ID3DDevice9::Present until the next draw update on the monitor. Apparently, using GLFW (a framework for OpenGL), you can call glfwSwapInterval(1) to turn on vsync. There's also wglSwapInterval, which I gather is a Windows extension in OpenGL. Avenging Dentist fucked around with this message at 09:14 on Dec 12, 2008 |
# ? Dec 12, 2008 09:12 |
|
Whilst farting I posted:
|
# ? Dec 12, 2008 11:20 |
|
Avenging Dentist posted:I don't see how it's crap, except that it has more overhead than some (but not all) other methods of measuring time. QueryPerformanceFrequency is required to return the same value each time for a given hardware configuration, and QueryPerformanceCounter is based on wall time. The only legitimate complaint I know of is that QPF/QPC doesn't work too well when dealing with buggy hardware/BIOSes.
|
# ? Dec 12, 2008 12:02 |
|
Some info on QPC/QPF: http://blogs.msdn.com/oldnewthing/archive/2007/07/05/3695356.aspx http://blogs.msdn.com/oldnewthing/archive/2008/09/08/8931563.aspx
|
# ? Dec 12, 2008 13:03 |
|
ultra-inquisitor posted:The idea behind quicksort is that you sort the data by swapping it around in-place. By splitting it up into two separate lists (less than and greater than pivot), you need to recombine the lists, which is closer to mergesort (which is actually the best way of sorting lists). The trick here is to pass two iterators into the function, which define the start and end of the (sub)list that you want to sort, rather than the actual list itself. Then recursion is simply a matter of updating where those iterators point to, and passing them back in. Don't forget to check for the termination condition where startIterator == endIterator. I guess I'm just confused about what'll happen when I recurse if I have a loop in there that splits up the initial list A into two separate lists. Every time I call it, it'll be splitting it into two different lists.
|
# ? Dec 12, 2008 16:08 |
|
Whilst farting I posted:I guess I'm just confused about what'll happen when I recurse if I have a loop in there that splits up the initial list A into two separate lists. Every time I call it, it'll be splitting it into two different lists. code:
edit: it's worth pointing out of course that doing quicksort this way is really an inefficient version of mergesort, one of the strengths of quicksort is that it can be done in-place. newsomnuke fucked around with this message at 16:43 on Dec 12, 2008 |
# ? Dec 12, 2008 16:39 |
|
Rottbott posted:I've found that the reported time can jump backwards on some dual core systems when the thread changes core. The only workaround we found that worked was setting the thread affinity to a particular core before the QPC call. QPC was reportedly fixed for Vista but at a huge execution cost. It already took thousands of cycles to execute on XP and it's much more expensive now
|
# ? Dec 12, 2008 18:09 |
|
ultra-inquisitor posted:You'll recursively split the list into lots of lists of size 0, and then the function stack will 'unwind' and you'll need to merge the lists back together. If you want to do quicksort that way, then your function will look like this: Ahhh, thanks! Recursion is always something that has kind of escaped me, and I knew it bore some really striking similarities to mergesort but I hadn't quite realized how. I wrote something that I think should otherwise work, but now I'm getting compiler errors at the recursive calls and I'm unsure of the syntax needed code:
quote:listSort.cpp In function `void quicksort(SinglyLL<T>&, bool (*)(T&, T&)) [with T = std::vector<std::string, std::allocator<std::string> >*]': This is the line in the main it's complaining about code:
code:
(needSwap)(*itr,*itr2) (*needSwap)(*itr,*itr2) (needSwap)(itr,itr2) but nothing I've tried will not give me an error for those two recursive calls. I'm admittedly very new to function pointers, and I'm absolutely clueless as to what the syntax should be. Whilst farting I fucked around with this message at 21:35 on Dec 12, 2008 |
# ? Dec 12, 2008 21:33 |
|
You're dereferencing needSwap when you do needSwap(a,b), which calls the function pointed to by needSwap and yields the return value (a boolean). You probably just want to pass the value of the pointer directly (i.e., without dereferencing). E.g.: code:
|
# ? Dec 12, 2008 21:49 |
|
ultra-inquisitor posted:edit: it's worth pointing out of course that doing quicksort this way is really an inefficient version of mergesort, one of the strengths of quicksort is that it can be done in-place. I don't understand why you think it's like mergesort. There's no merging that needs to be done as you know one of the lists is sorted and less than the pivot, and the other is sorted and greater than the pivot, and concatenating two lists together is a simple constant-time operation. Edit: In fact, if you're careful to work only with node pointers you can quicksort "in-place" in a different sense, and if T is a large object it might actually be faster than quicksorting an array. floWenoL fucked around with this message at 22:35 on Dec 12, 2008 |
# ? Dec 12, 2008 22:23 |
|
floWenoL posted:I don't understand why you think it's like mergesort. There's no merging that needs to be done as you know one of the lists is sorted and less than the pivot, and the other is sorted and greater than the pivot, and concatenating two lists together is a simple constant-time operation.
|
# ? Dec 12, 2008 22:38 |
|
Ack, I'm confused all over again. code:
Recursion
|
# ? Dec 13, 2008 03:44 |
|
Whilst farting I posted:It always just returns every time a list has one element or 0 elements, Isn't that what you want? It's what the top of your code does, anyway. Also, your for loop simply infinite-loops.
|
# ? Dec 13, 2008 04:15 |
|
floWenoL posted:Isn't that what you want? It's what the top of your code does, anyway. The for-loop determines which list to place each node in - but the function it uses to do that pops the head off of list A and places it in another list, so the head is constantly changing and it's necessary to reset it each time through. It doesn't loop infinitely. Isn't the case of 1 or 0 elements the base case? I'm not sure how to address that in the context of this function. That's what I'm confused about, every quicksort/mergesort algorithm I've seen requires that.
|
# ? Dec 13, 2008 04:42 |
|
Whilst farting I posted:Isn't the case of 1 or 0 elements the base case? I'm not sure how to address that in the context of this function. That's what I'm confused about, every quicksort/mergesort algorithm I've seen requires that. Also you don't need a whole list for the pivot, just a simple T will do.
|
# ? Dec 13, 2008 10:03 |
|
ultra-inquisitor posted:You're doing the recursion correctly, it's almost certainly a bug in your for-loop (can't tell because you haven't posted the full code). Put some prints in to make sure it's doing what you expect. I did put some prints in the for-loop, it's doing what I expect. It turns out that my problem was in my append function - there was an error in the compiler that I misread as an unused variable warning. Now my problem is that the list it's supposed to be returning by reference is returned as totally, completely empty. It has 0 elements. Here's my full code. code:
pop_front_push_front_elsewhere seems to work just fine - if I comment out everything after I first pop off the front after the variable declarations, quicksort will return the list passed by reference, and its size is appropriate. Let's say I give it the following numbers in a certain type of list: 53327 348554 54832 82435 90560 it will return 348554 54832 82435 90560 So the front was popped off, and the loop ran until its tail, 4 times, and didn't segfault, so it looks like the head and tail are being set appropriately. But if I run it with the full code, here's what the debug statements output (I didn't put them for when I pop off the pivot, should I? that seems to work okay, considering that it verifies that it pops off 53327, which would make 348554 bigger than everything else, so its sorting is correct) quote:after! size of A is 3 and size of after is 1 Normally the list is supposed to be printed before it says the sort time - but it seems to think the list is empty. It'll print just fine if I comment out everything after I pop the pivot, it'll print the last 4 numbers listed above. Here's my code for appendandclear. code:
|
# ? Dec 13, 2008 20:56 |
|
Whilst farting I posted:
|
# ? Dec 13, 2008 22:15 |
|
ultra-inquisitor posted:This is a memory leak, there's no need to create a new Node here, just do Node *tempHeadNode = head. appendandclear() shouldn't need to fiddle around with its internal pointers like this, pop_front_push_front_elsewhere() should handle everything on its own - it does this in the swap loop, why not in appendandclear? Because append needs to append one list to another, and there's no push back function - only a push front function. I need to trick the list into thinking the tail of one list is actually its front, so when it pushes to the "front" it's actually pushing it back.
|
# ? Dec 14, 2008 01:55 |
|
After you've finished the for loop, you've popped every item off A, so A is empty. Thus when you run appendandclear(), head is going to be NULL. And so tempHeadNode will be NULL, and after appending all the items onto A, you then set head back to NULL again, losing all the items.
|
# ? Dec 14, 2008 02:14 |
|
You're right - I've added some conditions to check for empty lists being appended/dealt with, and the list isn't returned as empty anymore, but it does return the lowest element in the list.quote:after! size of A is 3 and size of after is 1 I played around with appending a bit, and discovered that the list the sort returns is actually just the very first item appended to it - if I append the after list first, the list that returns will consist just of the highest element in the list, no matter what I append after it. I'm somehow keeping only the first list/element I append while losing everything else. So this tells me that the sort works, and that I've got major problems with how I'm setting my head and tail. Here's how I've modified appendandclear code:
code:
code:
How to approach this should be blindingly obvious but it's not coming to me. I know it has something to do with how I'm "appending" one list to another and how I'm setting the head and tail in that function but I can't get any further. Whilst farting I fucked around with this message at 04:14 on Dec 14, 2008 |
# ? Dec 14, 2008 04:11 |
Somewhere in my loving huge (tm) operating systems project, a there is a memblock->next = memblock. I can't do a simple search through the text, as the assignment happens when the program is running. (Lots of pointer dumbfuckery and the like.) What tools can I use other than gdb and ddd exist to help with this screaming headache?
|
|
# ? Dec 14, 2008 05:03 |
|
Jo posted:I can't do a simple search through the text, as the assignment happens when the program is running. All assignments happen when a program is running. (Excluding const PODs, etc). You could just write a regex and filter the results manually. Unless you're dealing with several million lines of code, this shouldn't be too bad. Alternately, you could use something like Intellisense and use "Find Symbol".
|
# ? Dec 14, 2008 05:11 |
|
How many places in your code are you actually assigning to memblock->next? I mean would it be reasonable to just assert(&memblock != &memblockToBeNext) before the assignment and backtrack from there to find the bug?
|
# ? Dec 14, 2008 05:20 |
Avenging Dentist posted:All assignments happen when a program is running. (Excluding const PODs, etc). Ehr, yes. That was poorly phrased. The assignment is the end result of a series of operations when I run the application. I.e. a->next = b; b->next = c; c->next = d; d->next = a; Remove c, b->next = d; Remove b, a->next = d; Remove d, a->next = a; The bug doesn't arise in small scale tests. It's large-scale 5 minute long stress tests that make it pop up. In a perfect world, I'd like to be able to set up a monitor that detects when the assignment obj->next = obj is made. Is this possible? TheSleeper posted:How many places in your code are you actually assigning to memblock->next? I mean would it be reasonable to just assert(&memblock != &memblockToBeNext) before the assignment and backtrack from there to find the bug? Only a few, and there are a number of checks in place to catch that sort of thing; making it all the more maddening when it shows up. Jo fucked around with this message at 05:42 on Dec 14, 2008 |
|
# ? Dec 14, 2008 05:21 |
|
Whilst farting I posted:How to approach this should be blindingly obvious but it's not coming to me. I know it has something to do with how I'm "appending" one list to another and how I'm setting the head and tail in that function but I can't get any further. code:
|
# ? Dec 14, 2008 11:41 |
|
Hi, I've got a month to program a sequencer in visual c++ with no prior knowledge of the language. It has to take an input such as a string of chosen notes, and play it out through midi out. Can anyone give me any general tips on how I might go about this? I have a book that should help me pick up what I need to do this. Expect to see me in this thread quite a bit!
|
# ? Dec 14, 2008 17:27 |
|
I have a question for C++ language nazis. Clearly it's unacceptable to call a virtual method on a NULL pointer. Is it acceptable to call a non-virtual method on a NULL pointer, from the standpoint of the language definition? It happens to work on g++, but I want to know whether it is required by the standard to work. many thanks
|
# ? Dec 15, 2008 03:46 |
|
theg sprank posted:I have a question for C++ language nazis. It doesn't even work in GCC, at least not for any reasonable value of "works": http://codepad.org/H8lxLv1U
|
# ? Dec 15, 2008 04:06 |
|
theg sprank posted:I have a question for C++ language nazis. I'm not sure about the standard, but in all the implementations that I've seen, it's safe if and only if the function doesn't access any member data (as in, use the this pointer). This basically makes it a static function though, so you would probably just refactor it that way. I'm sure the standard says it's undefined in general though, since it's a NULL deref technically.
|
# ? Dec 15, 2008 04:07 |
|
Avenging Dentist posted:It doesn't even work in GCC, at least not for any reasonable value of "works": Well yeah, obviously if you try to use member data it'll crash and burn. Here's some background: my University has a series of courses for people who just want to learn a language. I tutor several of these courses, including the C++ one. I notice a lot of people writing recursive code whose base cases go something like code:
Steampunk Mario posted:I'm sure the standard says it's undefined in general though, since it's a NULL deref technically. This is pretty much what I suspected, just looking for confirmation.
|
# ? Dec 15, 2008 04:36 |
|
|
# ? Jun 9, 2024 00:32 |
|
Quoth the Standard:ISO/IEC 14882-1998 §5.2.5 #3 posted:If E1 has the type "pointer to class X," then the expression E1->E2 is converted to the equivalent form (*(E1)).E2; ...
|
# ? Dec 15, 2008 04:47 |