|
shrughes posted:Just use `buttIter->->fart()` syntax. C++ code:
|
# ? May 24, 2013 16:47 |
|
|
# ? Jun 8, 2024 01:45 |
|
mobby_6kl posted:I was just dicking around with my (very basic) ray tracer on my laptop, and discovered that it seems to be roughly two times faster than running on the desktop where I originally wrote it. This wouldn't be too surprising since the laptop is like 5 years newer, but the processors are Core2 Q6600 and i7 2620m which should actually have similar overall and FLOPS performance, as far as I could tell from Intel's docs. The better handling of float denormals might be an especially important performance factor in your raytracer.
|
# ? May 24, 2013 16:50 |
|
mobby_6kl posted:I was just dicking around with my (very basic) ray tracer on my laptop, and discovered that it seems to be roughly two times faster than running on the desktop where I originally wrote it. This wouldn't be too surprising since the laptop is like 5 years newer, but the processors are Core2 Q6600 and i7 2620m which should actually have similar overall and FLOPS performance, as far as I could tell from Intel's docs. RAM (DDR2 vs. DDR3, I'm assuming), and the RAM path (integrated memory controller vs. chipset MC). I assume your raytracer quickly degenerates into a clusterfuck of decoherent rays, raping any kind of cache coherency or prefetch heuristic. Congratulations, you wrote a RAM latency benchmark.
|
# ? May 25, 2013 00:03 |
|
Still working on baby's first c++ app. I feel like there is a better way to do this and am looking for input(both on method and on the code). Basically, I have a square in an image, but it's a 'real' image, so the square can be oriented weird, like a diamond, and also with a warped perspective(not actually a square anymore at all). I'm going to apply a warpPerspective function it it, but first I need it's four corners. What I have is it's 'contour' which is just a vector containing all of the points of the square's perimeter. At first, I was just going to do the math and find the highest and lowest X and Y coordinates and call those the corners, but because rounded and 'weird' corners are highly likely, that could throw it off I think(I didn't try it). What I came up with is finding the rotatedRect of the box, then comparing all of the coordinates in my contour to it's corners and grabbing the ones closest. edit: For clarity, rotatedrect is just a function in this library that finds the smallest rectangle that encloses a set of coordinates. All estDistance does is produce a number for comparison, it's the distance formula without bothering to find the square root. code:
Obvious problems? I miss c#'s foreach statement, I haven't done any googling yet but is c++'s just much more limited?
|
# ? May 25, 2013 18:03 |
|
If you can use C++11, you can replace these loops with range-based versions alacode:
If the type of boxCorners is float[4] you can do the same thing, otherwise you can write code:
Implementation-wise, you could use a Hough transform on your contour to find its bounding quadrilateral and use that to find the corners. With your implementation as the angles of the square move away from 90/90/90/90 the corners of the rotatedrect will be nowhere near the actual corners. EDIT: And this will probably have little to no effect on speed, but I would change the code to loop over every point once and check it against every corner instead of what you have currently. FamDav fucked around with this message at 19:04 on May 25, 2013 |
# ? May 25, 2013 18:58 |
|
FamDav posted:If you can use C++11, you can replace these loops with range-based versions ala Ooooh that range based for loop stuff is handy, hadn't learned that yet. Auh, I misunderstood a rotatedrect, in my mind it created a minimum quadrilateral, not a minimum rectangle. I'll get to work on the hough transform.
|
# ? May 25, 2013 19:28 |
|
Why the 'const' in for(const auto &y : x) ? And why the &? I understand that's the 'address of' operator, but how does using it change what's being done? If you only used y instead of &y, would it be creating a copy of y at some point?
|
# ? May 25, 2013 19:43 |
|
I assume if it says it is a rectangle it is a rectangle, but you should double check. Also, your library may very well implement something which finds a bounding quad so use that instead. The ampersand in a type declaration means it is a reference, which means that the variable in question refers to the same bit of memory as the variable assigned to it. The const means that the variable cannot be mutated. This is useful for the compiler help you with not changing values you don't want to be changed, which can be particularly pernicious when you are using references. And your final assumption is correct, it will instead create copies of each element in the container instead of taking references.
|
# ? May 25, 2013 19:53 |
|
bobua posted:Why the 'const' in for(const auto &y : x) ? EDIT: oh, sorry, I forgot you were new to C++. Leaving this up for posterity. auto is basically template argument deduction against the type of the initializer. The initializer in a for-range loop is the result of dereferencing the iterator (with unary *), so yes, if you don't use &, you'll be copying the element into the induction variable. Whether that's actually a problem depends, of course. const is mostly communicative here, although if you have some weird custom operator* that doesn't return an lvalue reference (e.g. if it returns a proxy object like std::vector<bool>::iterator), it can be necessary.
|
# ? May 25, 2013 20:10 |
|
It's totally cool if I spam this thread with c++ programming questions not worth their own thread, right?code:
I always think I understand pointers, but then I get confused when I see code that puts the *\&'s before or after the variable, or on the datatype instead:( Why is the * on the unsigned char in line one, then prepending inp on line 7? Why does god hate me?
|
# ? May 26, 2013 20:55 |
|
bobua posted:I always think I understand pointers, but then I get confused when I see code that puts the *\&'s before or after the variable, or on the datatype instead:( Why is the * on the unsigned char in line one, then prepending inp on line 7? Why does god hate me? Where you place the * and & is a stylistic choice. These are all the same: code:
Line 1 is declaring inp to be a pointer to unsigned char whereas line 7 is dereferencing that pointer. xgalaxy fucked around with this message at 21:06 on May 26, 2013 |
# ? May 26, 2013 21:01 |
|
bobua posted:Why is the * on the unsigned char in line one, then prepending inp on line 7? Why does god hate me? bobua posted:What's the difference between how it's written and replacing 'unsigned char' with 'uchar'? I can't help with your other question because I have no idea what the type of 'img' is.
|
# ? May 26, 2013 21:09 |
|
xgalaxy posted:Where you place the * and & is a stylistic choice. These are all the same: and... char foo*; I assume? just wanna make sure. That makes way more sense than the convoluted reasoning I had... Is using the * later on stylistic also? bool *foo; if (foo) vs if (*foo) ?
|
# ? May 26, 2013 21:11 |
|
Ok, so using the * later 'dereferences' the pointer. So inp in the example would literally return a numerical memory address, while *inp would return what's at that memory address, correct? If that's the case, is *inp++ incrementing what's at the memory address, or the memory address? it would seem it would be incrementing what's at the memory address, but if that's the case, wouldn't it be changing the Image I'm working with, and not just moving to it's next pixel?
|
# ? May 26, 2013 21:19 |
|
char foo*; is gibberish. bool *foo; declares a pointer to an object of type bool. if(foo) evaluates the value of the pointer (a memory address) as a boolean expression which is probably not what you want to do if(*foo) dereferences the pointer and actually tests the value of the object (true or false).
|
# ? May 26, 2013 21:19 |
bobua posted:and... Notice that the only difference between the three you quoted is how the whitespace is distributed. You moved the star to be after the variable name instead of between the type and variable name. bobua posted:That makes way more sense than the convoluted reasoning I had... Here you declare foo as a pointer-to-bool. The value of foo is a pointer. Using the prefix * operator on the variable de-references the pointer, so the type of the expression (*foo) is bool. if(foo) means "if foo is a non-null pointer", while if(*foo) means "if the value pointed to by foo is not false". (fe:f,b)
|
|
# ? May 26, 2013 21:23 |
|
bobua posted:If that's the case, is *inp++ incrementing what's at the memory address, or the memory address? Also note that the expression inp++ uses the postfix form of the ++ operator, so the pointer will be dereferenced first and then incremented. There is also a prefix form which looks like *(++inp) where the pointer will be incremented first and then dereferenced.
|
# ? May 26, 2013 21:31 |
|
I'm working on a project from a textbook, and having the same problems as previous projects. My instructor helped me with those, but not very satisfactorily, so I'm hoping someone here can maybe explain what's going on a bit better. This book comes with a class "grid" that puts out a grid of dots and a mover facing in a cardinal direction (e.g. "v" for south). It only comes with the ability to turn left, and this project has me adding the abilities to turn right and turn around (by just turning left thrice or twice). I followed the instructions, adding "void turnAround();" and "void turnRight();" to the .h file and code:
Here are links to the code on Pastebin: grid.h grid.cpp test.cpp
|
# ? May 27, 2013 18:05 |
|
That code compiles and runs without errors for me with both clang and msvc. I suspect you have multiple copies of grid.h lying around and the wrong one was included.
|
# ? May 27, 2013 18:14 |
|
Plorkyeran posted:That code compiles and runs without errors for me with both clang and msvc. I suspect you have multiple copies of grid.h lying around and the wrong one was included. I just now deleted any extraneous copies of grid.h, removed it from the project, and added it back in, making sure that it's in the same folder as everything else. Now the compiler can't even find the loving file! How? I just added it! Edit: Turns out I had the wrong grid.cpp file File locating is apparently going to be the bane of my existence with coding.
|
# ? May 27, 2013 18:21 |
|
hooah posted:I just now deleted any extraneous copies of grid.h, removed it from the project, and added it back in, making sure that it's in the same folder as everything else. Now the compiler can't even find the loving file! How? I just added it! I thought IDEs are supposed to make your life easier, not harder
|
# ? May 27, 2013 21:12 |
|
hooah posted:I just now deleted any extraneous copies of grid.h, removed it from the project, and added it back in, making sure that it's in the same folder as everything else. Now the compiler can't even find the loving file! How? I just added it! Incidentally it doesn't matter to MSVC if you include a header file in the project or not. It only compiles the .cpp files. Including the header files is for your benefit, and maybe Intellisense's.
|
# ? May 27, 2013 23:43 |
|
Working on a quadratic formula class/program now. I've got the class working fine, but am having a problem with the output of the main program We're given the main program, which includes blocks like this:code:
code:
|
# ? May 28, 2013 00:27 |
|
Fix or don't use qe.display().
|
# ? May 28, 2013 00:33 |
|
Spatial posted:The i7 has hyperthreading so it can still run four threads at once even though there are only two cores. It can also dynamically increase its clock frequency when operating under the rated TDP. A Sandy Bridge i7 like that has a world of other architectural improvements over a Q6600; doubling performance per core sounds about right. Thanks. Doubling performance per core is roughly what I'd expect too, actually. What was unexpected is that the i7 was much faster overall, like almost twice as fast with half as many cores. I don't think Hyperthreading can explain this as the overall performance at best doubles when going from a single thread to four. karoshi posted:RAM (DDR2 vs. DDR3, I'm assuming), and the RAM path (integrated memory controller vs. chipset MC). I assume your raytracer quickly degenerates into a clusterfuck of decoherent rays, raping any kind of cache coherency or prefetch heuristic. Congratulations, you wrote a RAM latency benchmark. This makes sense... it seems that in some smaller scenes, the Q6600 is actually somewhat faster, but in the larger scene with many triangles it starts to fall way behind. I'll try to rig up some benchmark to see if there's a sharp drop off once the scene no longer fits into cache. At the moment I'm naively testing each ray against all objects so implementing an octree or some other acceleration structure should probably be the first priority, optimization-wise. But am I correct in thinking that this would also significantly improve the cache situation, as adjacent rays would likely be tested against the same small subset of objects, thus keeping them cached? Other then that, I'm not really sure what else could be done, since what happens then isn't very predictable.
|
# ? May 28, 2013 10:21 |
|
hooah posted:Working on a quadratic formula class/program now. I've got the class working fine, but am having a problem with the output of the main program We're given the main program, which includes blocks like this: Use a for loop and strlen to find the linebreak and replace it with a \0 instead.
|
# ? May 28, 2013 16:16 |
ratbert90 posted:Use a for loop and strlen to find the linebreak and replace it with a \0 instead. Wouldn't work. Notice, the qe.display() function is printing by itself, it doesn't return a string. Either modify the qe.display() function so it doesn't print, but instead returns an appropriate string, or add another function to the class to do that.
|
|
# ? May 28, 2013 16:31 |
|
nielsm posted:Wouldn't work. Ah, my mind glazed over and for some reason I just assumed he was using cin. my bad.
|
# ? May 28, 2013 16:55 |
|
Replace the buffer that cout writes to with one of those ostringstream buffers before calling the function.
|
# ? May 28, 2013 16:56 |
|
Use dup2 to redirect stdout into a pipe then read from that and
|
# ? May 28, 2013 16:57 |
|
I've got a question about implicit typecasting/typecast operators. I have a class "Interval" with the following definition (unnecessary cruft trimmed): code:
code:
|
# ? May 28, 2013 17:09 |
|
nielsm posted:Wouldn't work. I just removed an endl from display().
|
# ? May 28, 2013 17:09 |
|
mobby_6kl posted:This makes sense... it seems that in some smaller scenes, the Q6600 is actually somewhat faster, but in the larger scene with many triangles it starts to fall way behind. I'll try to rig up some benchmark to see if there's a sharp drop off once the scene no longer fits into cache. Correct. Optimization priority list: * cache * cache * cache * flops The primary rays are basically normal rasterization, they can be accelerated by a normal GPU wonderfully, because GPUs are really good at rasterization. Secondary rays are a horrible clusterfuck. Think of the typical scene: a cluster of mirror balls. Their reflections are all over the place, adjacent pixels lose all coherency and all FLOPS become cache misses and RAM waits. This kills GPUs, too. And yeah, not checking all objects vs. your rays will greatly help the primary rays' rasterization cache hit %. It will also accelerate the secondary rays hit detection cost and their cache footprint, allowing a bigger scene to be rendered before the cache gets trashed. Not everything is a mirror ball, there are also flat mirrors, which maintain a little bit of ray coherence.
|
# ? May 28, 2013 19:50 |
|
Here's something I thought was kinda strange. The following does not compile:code:
http://ideone.com/UlCXDN But if I instead use { 'a', '\0' } when creating the char-arrays, it compiles just fine. Why does it work like that?
|
# ? May 28, 2013 20:44 |
|
netcat posted:Here's something I thought was kinda strange. The following does not compile: I suppose it's because string literals are const.
|
# ? May 28, 2013 21:17 |
|
Edit: I guess I gave the fact it didn't work too much credit. Edit: for what it's worth, it doesn't work on the latest GCC either. seiken fucked around with this message at 21:26 on May 28, 2013 |
# ? May 28, 2013 21:18 |
|
Actually, I think it's probably just a bug in your compiler. It works for me with trunk clang. There's no reason that generalized initialization syntax shouldn't permit array initialization from a string literal.
|
# ? May 28, 2013 21:21 |
|
I'm not familiar with how the new brace-initialisation syntax actually works, but I'm pretty sure as soon as you pass a char* into a function then you can't initialise an array with it. vector is obviously using a function to initialise here, so I don't see why this could work. Is there some magic about initializer_list that preserves the string-literal-ness of the literal? Edit: oh, the structs get constructed before they get passed into the vector constructor, I guess? That makes sense. seiken fucked around with this message at 21:44 on May 28, 2013 |
# ? May 28, 2013 21:37 |
|
rjmccall posted:Actually, I think it's probably just a bug in your compiler. It works for me with trunk clang. There's no reason that generalized initialization syntax shouldn't permit array initialization from a string literal. Ah, OK. I see no reason why it wouldn't work either (especially when "regular" array initialization syntax works just fine), though I have no idea about the details behind initializer_list.
|
# ? May 28, 2013 21:41 |
|
|
# ? Jun 8, 2024 01:45 |
|
karoshi posted:Correct. Optimization priority list: Not that cache isn't important, but you implement an acceleration structure so that you can render a scene with a million triangles by doing collision tests with 4 triangles and 25 planes per trace. Less thrashing the cache is a nice side effect but in optimization its a far distant second to just improving the algorithmic efficiency of the intersection search. This is also why the most significant potential improvement after implementing an octree is implementing something faster than an octree -- octrees build fast but traverse (comparably, it's still an exponential improvement over nothing) slow. As for actually helping the cache cohere, the main thing to bear in mind is that packing data into minimal space matters. Rays will either cohere or not depending on the scene (usually not, in path tracing at least) and not much can be done about that. However, using an octree that takes 8 bytes of storage per node instead of 32 bytes means fitting 4 times as much of it in cache and that makes cache hits during traversal correspondingly more likely. This is also why texture compression (or at least not storing all textures as HDR floats because now you can) is still relevant when working with 40 GB of RAM on a render cluster rather than what happens to be available on some guy's GPU. Aside: we actually have a couple of billion-triangle scenes that take up 40 GB of RAM at work. Industrial design people: they really like their tiny details.
|
# ? May 28, 2013 22:22 |