Constant variable is changing but not in memory - c++

First of all, I am working in XCode C++ when I get the error. I declare a pointer variable as a constant and I set the value once. Then in the code a loop runs 3-5 times and the first time it is correct but then depending on the number of variables, the value of the coordinate changes to close to 0 (ie. 4.59163e-41). I know that the memory address does not change, just the value it holds does. Also I am working with really large amounts of data, and by that I mean between 2,000 and 20,000 coordinates. I'm sure I caused this with either a big or small problem so any help would be appreciated. Below is some of the code for the changing [not-so] constant variable:
I declare them in the header file as:
const float* m_xPointValues;
const float* m_yPointValues;
Then in the .cpp file I set them in the following function:
void ccGraphDisplay::setPointValues(float* xPointValues, float* yPointValues, unsigned numberOfPoints)
{
assert(xPointValues);
assert(yPointValues);
m_xPointValues = xPointValues;
m_yPointValues = yPointValues;
m_numberOfPoints = numberOfPoints;
....}
Then in the looping function I shift them but as far as I know this does NOT change their value:
for (unsigned i=0;i<m_numberOfPoints;++i)
{
shiftedXValue = (((m_xPointValues[i] - m_xAbsoluteMin)/(m_xAbsoluteMax-m_xAbsoluteMin))*(m_roi[2]-m_roi[0]))+m_roi[0];
shiftedYValue = (((m_yPointValues[i] - m_yAbsoluteMin)/(m_yAbsoluteMax-m_yAbsoluteMin))*(m_roi[3]-m_roi[1]))+m_roi[1];
}
To me this is a very odd error. I do not change the value of m_xPointValues or m_yPointValues anywhere else and in the largest sets of data only the end portion of the coordinates change. I also set the loop to print out the values at the beginning and end of the loop and the end is always the same as the beginning but then when the loop starts over is when the value of it changes.
Finally some of the debugging ideas I have already tried include:
1) Changing the pointer from storing floats to doubles
2) Changing the pointers to no longer be constant
3) Passing in constant values (both double and float)
Any help would be greatly appreciated (including ideas to try!).
Thanks!

This sounds like the locations pointed to by xPointValues and yPointValues, that you passed to setPointValues, do not have the same lifetime as m_xPointValues and m_yPointValues.

Related

Implementing custom atomic_add() which works with floats

I'm trying to follow the B.12 section of https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html for atomic add, which works with floats. Simply copying and pasting the code from there and changing the types to floats does not work because I can't perform the casting pointer casting from GLOBAL to PRIVATE, required for the atomicCAS operation. To overcome this I decided to use atomic_xchg() because it works with floats, with additional if statement to achieve same functionality as atomicCAS. However, this returns me varying answer when I perform addition on large float vector every time i run the program.
I've tried figuring out how to overcome the explicit conversion from GLOBAL to PRIVATE, but I honestly don't know how to do it so that when I perform addition, the address argument is changed instead of some temp variable.
kernel void atomicAdd_2(volatile global float* address, float value)
{
float old = *address, assumed;
do {
assumed = old;
if (*address == assumed) {
old = atomic_xchg(address, value + assumed);
}
else{
old = *address;
}
// Note: uses integer comparison to avoid hang in case of NaN (since NaN != NaN)
} while (assumed != old);
}
This is my implementation of atomicAdd for floats.
kernel void reduce_add(global const float* input, global float* output) {
float temp = 242.23f;
atomicAdd_floats(&output[0], temp);
printf(" %f ", output[0]);
}
This is the function where I supply the arguments to the atomicAdd_floats. Note that my input argument contains a vector of floats and output argument is simply where I want to store the result, specifically in the first element of the output vector output[0]; but instead when i printf(" %f ", output[0]); it shows my default initialisation value 0.
First of all, i'd suggest to remove the "kernel" keyword on the atomicAdd_2 function. "kernel" should be used only on functions you intend to enqueue from the host. 2nd, there are OpenCL implementations of atomic-add-float on the net.
Then, i'm a bit confused as to what you're trying to do. Are you trying to sum a vector and while having the sum in a private variable ? if so, it makes no sense to use atomicAdd. Private memory is always atomic, because it's private. Atomicity is only required for global and local memories because they're shared.
Otherwise i'm not sure why you mention changing the address or the GLOBAL to PRIVATE.
Anyway, the code from the link should work, though it's relatively slow. If the vector to sum is large, you might be better off using a different algorithm (wtth partial sums). Try googling "opencl parallel sum" or such.

C++ - Operating on the bits in a floating point value

I'm trying to write a function that will reinterpret a set of bytes as a float. I have viewed a Stackoverflow question which lead me to try reinterpret_cast<>() on an array of characters, and I started experimenting with splitting a float into chars and then reassembling it again, but that only gives me seemingly random numbers rather than what I think the value should be, as the output is different each time. A few different examples are:
1.58661e-038
3.63242e-038
2.53418e-038
The float variable should contain the value 5.2.
Compiling the code:
float f = 5.2;
unsigned char* bytes = reinterpret_cast<unsigned char*>(&f);
float f1 = reinterpret_cast<float&>(bytes);
std::cout << f1 << std::endl;
gave me
1.75384e-038
And then of course, a different number each time the program is run. Interestingly, however, if I put the code in a loop and execute it several times in a single run, the output stays consistent. This leads me to think it might be a memory location, but if so, I'm not sure how to access the real value of the variable - the dereference operator doesn't work, because it's not a pointer.
So my question is - How can I split a variable of type float (and later on, a double) into individual bytes (allowing me to modify the bits), and then reassemble it.
Any help would be greatly appreciated.
bytes is a pointer.
Change
float f1 = reinterpret_cast<float&>(bytes);
to
float f1 = *reinterpret_cast<float*>(bytes);
// Cast to a different pointer... ^
// ^ ...and dereference that pointer.

What uses more memory in c++? An 2 ints or 2 functions?

I am writing in c++ for the Nintendo DS (With 4MB of RAM). I have a button class that stores data like the x,y location and length. Which of the following would take less memory?
.
Method 1, class variables length, x, y, and halfPoint
Button::Button(int setX, int setY, int setLength)
{
x = setX;
y = setY;
length = setLength;
halfPoint = length/2;
}
//access variable with buttonName.halfPoint
Method 2, class variables length, x and y
Button::Button(int setX, int setY, int length)
{
x = setX;
y = setY;
length = setLength;
}
int Button::getHalfPoint()
{
return length/2;
}
//access variable with buttonName.getHalfPoint()
Any help is appreciated. (And in the real code I calculate a location much more complex than the half point)
The getHalfPoint() method will take up less room if there are a lot of Buttons. Why? Because member functions are actually just implemented by the compiler as regular functions with an implied first argument of a pointer to the object. So your function is rewritten by the compiler as:
int getHalfPoint(Button* this)
{
return this->length/2;
}
(It is a bit more complicated, because of name mangling, but this will do for an explanation.)
You should carefully consider the extra amount of computation that will have to be done to avoid storing 4 extra bytes, however. And as Cameron mentions, the compiler might add extra space to the object anyway, depending upon the architecture (I think that is likely to happen with RISC architectures).
Well, that depends!
The method code exists exactly once in memory, but a member variable exists once for each object instance.
So you'll have to count the number of instances you create (multiplied by the sizeof the variable), and compare that to the size of the compiled method (using a tool like e.g. objdump).
You'll also want to compare the size of your Button with and without the extra variable, because it's entirely possible that the compiler pads it to the same length anyway.
I suggest you declare the getHalfPoint method inside your class. This will make the compiler inline the code.
There is a possibility that the code in the function is one assembly instruction, and depending on your platform, take the size of 4 bytes or less. In this case, there is probably no benefit to have a variable represent the half of another variable. Research "right shifting". Also, to take full advantage, make the variable unsigned int. (Right shifting a signed integer is not defined.)
The inline capability means that the content of the function will be pasted wherever there is a call to the function. This reduces the overhead of a function call (such as the branch instruction, pushing and popping arguments). The reduction of a branch instruction may even speed up the program because there is no flushing of the instruction cache or pipeline.

Largest floating point variable

The program takes for parameter one double and its doing computation with long float point values. eg double myvar= n*0.000005478554 /298477.
The problem is that im not sure that the real computational value is inserted to myvar.
because whenvever i change n it produce the same thing cout<<"myvar ="<<myvar;
What is the biggest type in c++ that can be used for maximum accuracy? Does a buffer overflow caused by this code because double variable cant hold too much info ? If yes what can happen and how can i detect it for later use?
double will hold values much smaller (and bigger) than 0.000005478554 /298477. Any problem that you have is almost certainly caused by a bug in your code. Show it!
Try to reduce your problem to a few lines. This kind of problems can be reproduced with something as small as
#include <iostream>
int main() {
double myvar = 7 * 0.000005478554 /298477;
std::cout << myvar;
}

C++: float value reused across iteration

Let's look at the following piece of code which I unintentionally wrote:
void test (){
for (int i = 1; i <=5; ++i){
float newNum;
newNum +=i;
cout << newNum << " ";
}
}
Now, this is what I happened in my head:
I have always been thinking that float newNum would create a new variable newNum with a brand-new value for each iteration since the line is put inside the loop. And since float newNum doesn't throw a compile error, C++ must be assigning some default value (huhm, must be 0). I then expected the output to be "1 2 3 4 5". What was printed was "1 3 6 10 15".
Please help me know what's wrong with my expectation that float newNum would create a new variable for each iteration?
Btw, in Java, this piece of code won't compile due to newNum not initialized and that's probably better for me since I would know I need to set it to 0 to get the expected output.
Since newNum is not initialized explicitly, it will have a random value (determined by the garbage data contained in the memory block it is allocated to), at least on the first iteration.
On subsequent iterations, it may have its earlier values reused (as the compiler may allocate it repeatedly to the same memory location - this is entirely up to the compiler's discretion). Judging from the output, this is what actually happened here: in the first iteration newNum had the value 0 (by pure chance), then 1, 3, 6 and 10, respectively.
So to get the desired output, initialize the variable explicitly inside the loop:
float newNum = 0.0;
C++ must be assigning some default
value (huhm, must be 0)
This is the mistake in your assumptions. C++ doesn't attempt to assign default values, you must explicitly initialise everything.
Most likely it will assign the same location in memory each time around the loop and so (in this simple case) newNum will probably seem to persist from each iteration to the next.
In a more complicated scenario the memory assigned to newNum would be in an essentially random state and you could expect weird behaviour.
http://www.cplusplus.com/doc/tutorial/variables/
The float you are creating is not initialised at all. Looks like you got lucky and it turned out to be zero on the first pass, though it could have had any value in it.
In each iteration of the loop a new float is created, but it uses the same bit of memory as the last one, so ended up with the old value that you had.
To get the effect you wanted, you will need to initialise the float on each pass.
float newNum = 0.0;
The mistake in thoughts you've expressed is "C++ must be assigning some default value". It will not. newNum contains dump.
You are using an uninitialized automatic stack variable. In each loop iteration it is located at the same place on the stack, so event though it has an undefined value, in your case it will be the value of the previous iteration.
Also beware that in the first iteration it could potentialliay have any value, not only 0.0.
You might have got your expected answer in a debug build but not release as debug builds sometimes initialise variables to 0 for you. I think this is undefined behaviour - because C++ doesn't auto initialise variables for you, every time around the loop it is creating a new variable but it keeps using the same memory as it was just released and doesn't scrub out the previous value. As other people have said you could have ended up with complete nonsense printing out.
It is not a compile error to use an uninitialised variable but there should usually be a warning about it. Always good to turn warnings on and try to remove all of them incase something nastier is hidden amongst them.
Using garbage value in your code invokes Undefined Behaviour in C++. Undefined Behavior means anything can happen i.e the behavior of the code is not defined.
float newNum; //uninitialized (may contain some garbage value)
newNum +=i; // same as newNum=newNum+i
^^^^^
Whoa!!
So better try this
float newNum=0; //initialize the variable
for (int i = 1; i <=5; ++i){
newNum +=i;
cout << newNum << " ";
}
C++ must be assigning some default value (huhm, must be 0).
C++ doesn't initialize things without default constructor (it may set it to something like 0xcccccccc on debug build, though) - because as any proper tool, compiler "thinks" that if you haven't provided initialization then it is what you wanted. float doesn't have default constructor, so it is unknown value.
I then expected the output to be "1 2 3 4 5". What was printed was "1 3 6 10 15".
Please help me know what's wrong with my expectation that float newNum would create a new variable for each iteration?
Variable is a block of memory. In this variable is allocated on stack. You didn't initialize it, and each iteration it just happen to be placed on the same memory address, which is why it stores previous value. Of course, you shouldn't rely on such behavior. If you want value to persist across iterations, declare it outside of loop.
Btw, in Java, this piece of code won't compile due to newNum not initialized
BTW, in C++ normal compiler would give you a warning that variable is not initialized (Example: "warning C4700: uninitialized local variable 'f' used"). And on debug build you would get crt debug error (Example: "Run-Time check failure #3 - The variable 'f' is being used without being initialized").
and that's probably better
Negative. You DO need uninitialized variables from time to time (normally - to initialize them without "standard" assignment operator - by passing into function by pointer/reference, for example), and forcing me to initialize every one of them will be a waste of my time.
I don't do too much C++ since last month, but:
The float values is newly allocated for each iteration. I'm a bit surprised about the initial zero value, though. The thing is, after each iteration, the float value runs out of scope, the next step (the reenter of the loop scope) first reallocates the float memory and this will often return the same memory block that was just freed.
(I'm waiting for any bashing :-P)