Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
schnarf
Jun 1, 2002
I WIN.
I've got a class inheritance question. I'm writing a scheduler using templates, so that I'll have a generic framework for the scheduler, and the actual process function is virtual so that I can write a variety of schedulers for whatever datatype and scheduling algorithm I want. This is for an assigment. My question is, the schedulers that I implement, inheriting from my base class Scheduler<T> will not need to be templated; they'll use only one datatype because the algorithm will be specific to that datatype. How do I specify that the inherited class isn't templated, but rather uses a specific datatype?

Adbot
ADBOT LOVES YOU

schnarf
Jun 1, 2002
I WIN.

Staggy posted:

Hi, I'm having some problems with linker errors when compiling a small test program. I'm using C++, with SDL, and whenever I try to use a vector I get the error

When i say 'use', I mean that

is okay, but

is not.
SDL on it's own is fine, and vectors on their own are fine, but the two don't seem to want to mix.

I'm using Visual C++ 2008 Express Edition, and I've seen various 'solutions' to this problem. However, they are all way over my head, and I can't work out what I'm supposed to be changing to solve it. Some talk about different library versions, and 'Debug vs. Release' settings, but I have no idea what these amount to.

Can anyone help? I can provide project settings on request.

I apologise for the low-level of the problem.
Can you describe more about the different files you have, where the SDL code is and where your code is, etc?

schnarf
Jun 1, 2002
I WIN.

bcrules82 posted:

whats the best way to extact the even bits (of a uint64_t) and stick them in a uin32_t? looking for a macro here

I'll show you taking an 8-bit type and extracting the even bits, and you can extend it to 64:

code:
#define EVENBITS(a) (a & 1) | ((a & (1<<2)) >> 1) | ((a & (1<<4)) >> 2) | ((a & (1<<6)) >> 3)
The pattern is, left shifts increase by two (this is the part that grabs the even bits), and right shifts increase by one (this part moves them over to where they belong).

schnarf
Jun 1, 2002
I WIN.

DontMockMySmock posted:

code:
#define nfreq 90
float chisquared(float coef, float index, float pixel[nfreq],float fq[nfreq]){
  float sum=0;
  int i=0;
  for(i=0;i<nfreq;i++) {
    sum=sum+(pow(pixel[i]-coef*pow(fq[i],index),2))/(coef*pow(fq[i],index));
    }
  return sum;
}
Given that all of the input variables are always positive and nonzero, how could this code ever return NaN? Because it does, all the time.
The only thing I could figure was if fq was ever negative and index was a power that would result in imaginary numbers. But fq is (in the main code) read from a file, which contains only positive numbers, and I checked that it read correctly, all positive. What else could cause it to return NaN?
Thanks in advance.
Break it down into a bunch of intermediate calculations, and then use a bunch of asserts that they fall into a valid range (i.e. the denominator is nonzero, the pow() calls don't return NaN, etc.

schnarf
Jun 1, 2002
I WIN.
What does the destructor for Image do? Is it possible that the constructor does something with the pointer to img and then something funky happens in the destructor?

schnarf
Jun 1, 2002
I WIN.

hexadecimal posted:

EDIT: Ok, I am a retard. Of course, it is to preserve negative number's sign and divide or multiply it by 2^n where n is the amount you shift by. But is this still done in software, or does the hardware know which numbers are signed or not?
The hardware has no way of knowing just given the data whether it's signed or not, obviously. Some platforms have separate instructions for arithmetic vs logical shifts. Basically my point is, the bits representing the number don't contain any information on how to interpret them. Just given 32 bits, you don't know it's a float, integer, or unsigned integer, for example. It's how you treat that data that determines what it is.

schnarf
Jun 1, 2002
I WIN.

heeen posted:

code:
float costable[8][8][64];
//...
factor= something;
for(unsigned int p=0;p<64;p++)
pixels[component][sampling_y*max_sy+sampling_x][p] += factor * costable[fy][fx][p];
Is it possible to speed up the loop by using SSE instructions, doing 4 multiply-add operations in parallel?
Does factor not change in the loop, or is the actual code much different? If it's the same, you can just factor it out, i.e. sum up all those values of costable, and then afterwards multiply by factor. Distributive property.

EDIT: I'm a retard.

schnarf fucked around with this message at 18:28 on Jan 17, 2009

schnarf
Jun 1, 2002
I WIN.

Jewdicator posted:

Can you pass values defined with #define as parameters?

I tried to do this with...

code:
#define FIVE 5;

int main{
//stuff
isPrime(FIVE);
//stuff
}

isPrime is expecting an int, casting FIVE to an int doesn't help either. The errors it gives me are unhelpful:

error C2143: syntax error : missing ')' before ';'
error C2059: syntax error : ')'

of course if i replace "FIVE" with 5 it works fine.
This is why you go:
code:
const int FIVE= 5;

schnarf
Jun 1, 2002
I WIN.

avatar382 posted:

Thanks.

So I did some googling on void pointers, and apparently you need to cast them to some specific type before they can be de-referenced.

I saw some example code where this was done, it looked like this:


code:
void Print(void *pValue, Type eType)  
{  
    using namespace std;  
    switch (eType)  
    {  
        case INT:  
            cout << *static_cast<int*>(pValue) << endl;  
            break;  
        case FLOAT:  
            cout << *static_cast<float*>(pValue) << endl;  
            break;  
        case STRING:  
            cout << static_cast<char*>(pValue) << endl;  
            break;  
    }  
}  
My question now is: What exactly is the Type type?

If I have an object of class Foo referenced by a void pointer, can I do something like this:

code:
void Print(void *pValue, Type eType)  
{  
    using namespace std;  
    switch (eType)  
    {  
        case INT:  
            cout << *static_cast<int*>(pValue) << endl;  
            break;  
        case FLOAT:  
            cout << *static_cast<float*>(pValue) << endl;  
            break;  
        case Foo:  
            cout << static_cast<Foo*>(pValue) << endl;  
            break;  
    }  
}  
The Type type is an enumeration, and it's user created. It's basically a pretty integer. Somewhere else in the code they would have gone:
code:
enum Type {
INT, FLOAT, STRING
};
The better way to do what they've done is overloading:
code:
void Print(int *pValue)  
{
     cout << *pValue << endl;  
}  

void Print(float *pValue)  
{
     cout << *pValue << endl;  
}  
And so on.

schnarf
Jun 1, 2002
I WIN.

weldon posted:

I'm trying to implement a polynomial class in C++, and I keep getting errors saying my member function isn't allowed to access the private variables, and this occurs throughout the entire code in many different places. Any idea why?

A function with the error is listed below, along with a summarized error code.

code:
#include <iostream>
using namespace std;
class polynomial {
      public:
             polynomial ();
             polynomial (const polynomial & other);
             polynomial (int D);
             polynomial (int D, int * C);
             ~polynomial ();
             polynomial & operator = (const polynomial & other);
             polynomial operator + (const polynomial & other) const;
private:
              int d;
              int * c;
};
code:
//assignment operator
polynomial:: polynomial & operator = (const polynomial & other){
             delete[] c; //delete old array (to the left of = sign)
             c = new int[other.d + 1] ; //create new array = to the size of the one to the right of the = sign
        d = other.d; //sets new degree value to that of the new array
    for (int i =0 ; i <= other.d; i++){
        c[i] = other.c[i];
    }   
    return(this) ;
}
code:
`int polynomial::d' is private within this context  (same thing with c)
You need to declare it
code:
polynomial:: polynomial & polynomial::operator = (const polynomial & other) {
Or just stick the whole cpp file in namespace polynomial and avoid the ugliness.

schnarf
Jun 1, 2002
I WIN.

ultra-inquisitor posted:

code:
class Foo
{
	friend std::ostream& operator << (std::ostream& os, const Foo& a_var);

	int m_type;
	union
	{
		int m_int;
		float m_float;
	};
	
	// Member functions
	// ...
};
Why does sizeof(Foo) give me 12? Is there some odd padding going on, or is there something in the member functions which might be taking up space?
I'm betting the union isn't 4 bytes as you'd expect. The union size is basically up to the compiler. Somebody else can quote the spec better than I can, but the compiler is probably padding the union for whatever reason.

schnarf
Jun 1, 2002
I WIN.
What's the class being used for? It sounds like there's gotta be a nicer way to do that.

schnarf
Jun 1, 2002
I WIN.

Vanadium posted:

I meant something that is to %d as %s is to %c :(

You can read in a single integer, say, 12345, and use the modulus and integer division operators to read out digits.

schnarf
Jun 1, 2002
I WIN.
Do this:
code:
bubbleSort(&Victor[0], Victor.size());
Also yeah use vector all you want.

Edit: Maybe I can explain a little more. Once you're done with the for loop you can't use "j" since you defined it there. Think about the arguments you were passing to it in the example you posted, and whether those arguments were right. What is j supposed to be there, and why did you choose 10? You want to pass bubbleSort the address of the beginning of your data to sort, and how many elements it has. Victor[0] returns a reference to the first element of the vector, and putting the & before it gives the address of that. Victor.size() is pretty self-explanatory.

schnarf fucked around with this message at 04:07 on Oct 7, 2009

schnarf
Jun 1, 2002
I WIN.

A MIRACLE posted:

Thank you~! But what is the purpose of the braces on line six of your version?
Do you get the syntax for initializers in the constructor? He's declaring a function. The initializer list that precedes it initializes the variables, and the braces indicate the body of the constructor. In this case the constructor does nothing besides initialize the variables in the initializer list.

It could be like:

code:
Date() : month(1), day(1), year(1885) {
cout << "Date() constructor << endl;
}

schnarf
Jun 1, 2002
I WIN.

Nahrix posted:

I have a piece of code where I have written a brute force algorithm to solve a problem, but I'm sure that there should be some equation to perform this task instead:

I have a string that has a lexicographic value, ie "abc", or "dfwz" (example of a bad value would be "aabc" or wxya"). I'm trying to convert this value to an int, by saying 'a' = 1, and counting up.

ie:
a = 1
b = 2
...
z = 26
ab = 27
ac = 28
ad = 29
...
az = 51
bc = 52
bd = 53
be = 54

etc..

While my current solution works fine, it's driving me crazy thinking that I can run it faster.
Think of it as counting in base 26. First assign a value 0-25 to each letter. Then they get multiplied by powers of 26 depending on their place.

I.e. abc = a*26^0 + c*26^1 + e*26^2 = 0*26^0 + 2*26^1 + 4*26^2...

And you can add 1 at the end if you want cause you seem like you want it to start at 1 instead of 0.

schnarf
Jun 1, 2002
I WIN.
By the way, your program is going to accept 0 and 32 for the day, and 0 and 13 for the month.

schnarf
Jun 1, 2002
I WIN.

Avenging Dentist posted:

And, you know, any negative number.
C++ supports those?

schnarf
Jun 1, 2002
I WIN.
To put it constructively, why not:

code:
#include<iostream>
#include<cstdlib>
#include"ScheduleBlock.h"
#include"MachineSchedule.h"

using namespace std;

int main()
{
	MachineSchedule mySched;
	ScheduleBlock *newBlock;

	for (int i=0; i<15; i++)
	{				

		int jobID= i+1;
		int startTime= rand();
		int processTime= rand();
		int ESTime= rand();
		nint LFTime= rand();
		mySched.addBlock(jobID,startTime,
                    processTime,ESTime,LFTime);
	}

	mySched.printSchedule();

	return 0;
}
My only guess is maybe you were trying to do something like:
code:
#include<iostream>
#include<cstdlib>
#include"ScheduleBlock.h"
#include"MachineSchedule.h"

using namespace std;

int main()
{
	MachineSchedule mySched;
	ScheduleBlock *newBlock;

	for (int i=0; i<15; i++)
	{				
		newBlock= new ScheduleBlock;

		newBlock->jobID= i+1;
		newBlock->startTime= rand();
		newBlock->processTime= rand();
		newBlock->ESTime= rand();
		newBlock->LFTime= rand();
		mySched.addBlock(newBlock);
	}

	mySched.printSchedule();

	return 0;
}
The deal with new and delete is (oversimplified): When you use new, it reserves a block of memory, and gives you a pointer to it (just the address of that block of memory). If you use new, and don't call delete, and you're running for a while, you'll keep reserving memory, and never indicating that you're done with it, and you'll use up way more memory than necessary. This is bad. On the other hand if you don't think things through and call delete and then need that memory somewhere else, you may be reading garbage later on. You need to think through, where is that block of memory used (say you allocate some memory and pass a pointer to it to some other function on another thread), and at what point can you guarantee you're done with it. Explicitly managing your memory like this is necessary sometimes but on the whole it requires a lot of thought and is really prone to bugs because we make mistakes. Whenever possible use the new smart pointers: scoped_ptr and shared_ptr.

In your case, you probably need to allocate some memory for each element in the linked list, and it shouldn't be deleted till the linked list is deleted, and it should be deleted when the linked list is deleted.

Can you show the interfaces for MachineSchedule and ScheduleBlock?

schnarf
Jun 1, 2002
I WIN.

Stavros posted:

Oops you're right. I guess I meant to do proj.push_back(0) instead. Thanks.
And maybe you're not intending to do this, but if you want a datatype to hold a vector in R3, make a datatype for it, don't use std::vector; that's not what it's for.

schnarf
Jun 1, 2002
I WIN.
Yeah in this case there's no reason to manually allocate and free the memory. Just use a vector.

schnarf
Jun 1, 2002
I WIN.

mantralord posted:

I have a minor concern over templates that I've always wondered about. Does template instantiation of a class (say, an STL container) with multiple types negatively affect the performance of a program by increasing code size and thus putting more pressure on the CPU cache? An STL container will have inherent performance advantages over a similar implementation in C, by avoiding void* arrays and/or avoiding having to store the size of each item and calculating offsets with that, etc. But I've always wondered about the adverse performance multiple instantiations might have on the cache, across a single program or even from taking into consideration multiple large programs running at once, each having multiple arbitrary template instantiations.

So basically, is this a legitimate concern or a non-issue?
If it does become an issue, one technique is to wrap common code that doesn't depend on the template parameters in another non-templated class, and have that be a private member of the templated class. I think some STL implementations use this.

Edit: Yeah, like what's being done in that link posted above. You can do that for member functions too.

schnarf
Jun 1, 2002
I WIN.

tractor fanatic posted:

Ah, thanks. If I'm certain that classes from the one hierarchy never meet classes from the other hierarchy until at the very end, would it be acceptable to make, say, MovingRectangle inherit from Rectangle normally, and BitmapRectangle inherit from Rectangle virtually, or is that a terrible idea?
I don't know what exactly you're trying to do, but try to do this with composition instead. Make a class to handle drawing logic, and make a class to handle moving, and the class you want to inherit from both should instead have one of each of these objects. Prefer to merge together functionalities by composition; inheritance should be used when you want a common interface.

schnarf
Jun 1, 2002
I WIN.

Dooey posted:

The constructors and destructors for Point:

code:
template<typename T> Point<T>::Point() {
}

template<typename T> Point<T>::Point(T newX, T newY) {
    x = newX;
    y = newY;
}

template<typename T> Point<T>::~Point() {
}
and the whole thing: http://codepad.org/a9Gvyb8s

Also I'm trying not to fall into any bad practices with this project, so if you see anything stupid or smelly that I'm doing, please tell me :)
It's just a small thing, but you should use an initializer list in the constructor. In this case it probably makes no difference, but in general doing it your way could cause the compiler to first default construct the member variables, and then reassign them.
code:
template <typename T> Point<T>::Point(T newX, T newY) :
    x(newX),
    y(newY) {
}

schnarf
Jun 1, 2002
I WIN.

Grazing Occultation posted:

That's the thing. There are no type conversions taking place. It's literally just a line like this returning NaN:

double x = atan2(a, b);

Where a and b are both valid angles.

If I repeat that calculation it doesn't fail, presumably because I've changed the program enough to bump it away from whatever odd luck caused it.

I'm not sure if anyone here can solve it. I was just hoping that someone would say "that's a weird problem; maybe it's X?" and then I'd have a starting point. :( It's the sort of hard-to-repeat oddity that makes me immediately think memory corruption but I can't find any.


Nope. This is all dead simple C. There's nothing the slightest bit more exotic than DLL exports.
You could try making a wrapper function for atan2 that does something like dumping the floating point registers, calls atan2(), and then breaks if it returned an unexpected value, and calling that wrapper instead to debug the problem.

schnarf
Jun 1, 2002
I WIN.

Grazing Occultation posted:

This is a good idea. I might give that a shot - even if the problem is somewhere else, maybe it'll give me more clues.
Ahh, one other thought, and sorry for how vague it is. If I remember right, some of my coworkers ran into some mysterious bug that resulted from something to do with calling conventions. It was something like, there was some function that had the wrong calling convention (possibly it was that the prototype didn't have the correct calling convention), and that function was passed/returned floats. As a result, the floating point stack would occasionally end up in a weird state. You could check to see if anything along these [extremely vague] lines applies to your case. I'll try to remember to ask them about that on Monday.

schnarf
Jun 1, 2002
I WIN.

Ledneh posted:

Thanks for the assessment. I'm really pretty rookie myself, only three or so years post-college experience, so my thoughts of the situation came down to

"I'm tired of people (self included) loving up deletions, I'm tired of not knowing who owns what data, and I am sure as poo poo tired of being the one who has to track DOWN all of those memory leaks and double deletes when things break, so let's move to shared pointers or a garbage collector and be loving DONE with it."

I love my job, I really do, but memory management is dicks :(
I think maybe using shared_ptr all over the place is overkill, but if you have a case where an object owns another, it's a no-brainer just to use a scoped_ptr.

schnarf
Jun 1, 2002
I WIN.

Rocko Bonaparte posted:

If everybody's talking about smart pointers again I thought I'd bring up what I consider to be something of a design/elegance problem, but I bet there's a little but of C++ magic that'll solve it. I created a template for handling arrays pretty much so I could have bound-checked versions as well as have an accessible length accessor. I was getting fed up passing a length around for everything, but I didn't want to resort to structures that required bounds checking for any access operators. I am doing a lot of FP math on these arrays and would prefer to keep it quick.

The data comes from a much larger pool and can be thrown all over the place. Something could be charting it while other things could be using that data to perform calculations. In this case I went with Boost's shared pointers. The larger data pool should be resident across the life of the program, so I suppose I could make it manage the ultimate destruction of the data. However, as I nibble on this code I thought this might not always be true. So I switched to wrapped all those template instantiatons in a shared pointer.

Now I have a problem where I can't do things like an array subscript operator straight off the pointer. For now, I implemented a get() for an unchecked access, versus at() which I believe is STL's way of doing a bounds-checked access. But I do like being about to subscript. Is there a good way to have the smart pointer while being able to subscript?

Can you be a little more specific about what you're trying to do? I feel like there's probably a more elegant way to do what you're trying to accomplish.

schnarf
Jun 1, 2002
I WIN.

nop posted:

I found MinGW really useful. I think there's a standard installer now. Although when installed it, it just unpacked to a folder and I had to set a path variable to the bin directory. From there I'd just edit my files in notepad++ and compile from the command line.

There may be easier methods out there, but for simple programs this is probably the fastest.

For anybody on Windows, I really think it makes sense to get VC++ Express. It's a really great IDE, and easy to set up.

schnarf
Jun 1, 2002
I WIN.

roomforthetuna posted:

And thanks for the correction of char* to const char* (just a mistake, inevitable when 'coding' direct into a forum) and __inline to inline, same thing, habit. (You're right, the reason for inline there isn't anything to do with efficiency, it's just my lazy convention for the sake of little set/get functions being defined in the header to save a little effort.)
If you define a member function inside a class definition, it's automatically inline.

schnarf
Jun 1, 2002
I WIN.

nielsm posted:

...
You can also look into using smart pointers instead.

Just do this; don't bother with manual memory management. Make a vector< shared_ptr<CBase> >.

schnarf
Jun 1, 2002
I WIN.

A MIRACLE posted:

Is it possible to use STL sort on something like

vector< vector< pair<int, myclass> > >

(sorting by the int)

I want to find out before I get in too deep.

To sort the innermost or outermost vector? In either case, yes; write a comparator:
code:
struct MyBizarreComparison {
    bool operator()( const vector< vector< pair<int, myclass> > >& a, const vector< vector< pair<int, myclass> > >& b ) {
        // make whatever comparison you want, and return whether you think a < b
    }
};

vector< vector< pair<int, myclass> > > vec;
// ...
std::sort( vec.begin(), vec.end(), MyBizarreComparison() );
The operator() function should behave like the < operator for your datatype.

schnarf
Jun 1, 2002
I WIN.

GrumpyDoctor posted:

Shouldn't argument type of operator () be either const vector< pair<int, myclass> > & or const pair<int, myclass> &?
Yeah, my bad, you're totally right. Sorry!

schnarf
Jun 1, 2002
I WIN.

Modern Pragmatist posted:

I'm working on converting a bunch of algorithms from Matlab to C because Matlab is painfully slow at pretty much everything. For loops aren't nearly as inefficient in C as they are in Matlab but all of the Matlab code utilizes lots of linear algebra routines. Would using a package like LAPACK be beneficial for both speed and conversion?
LAPACK et. al. are good. It'll be a waste of time for you to write all that stuff. If you have any interest in using C++, Eigen is probably pretty great too, and it integrates nicely with the language and uses templates to make fast code. Compile times are slow though.

schnarf
Jun 1, 2002
I WIN.

TasteMyHouse posted:

TEMPLATE QUESTION

I've got a templated vector class (the same class I was posting about back in march / april), backed by an instance of boost::array. For compactness, I want to be able to write a ctor or a factory function like so:
code:
typedef vect<float,2> vect2f;
vect2f MakeVect(float a, float b)
{
   vect2f v;
   v[0]=a;
   v[1]=b;
   return v;
}

typedef vect<float,3> vect3f;

vect3f MakeVect(float a, float b, float c)
{
   vect3f v;
   v[0]=a;
   v[1]=b;
   v[2]=c;
   return v;
}
And so on...

Is there a way to write a template that will generate these kinds of functions for me, using Boost or C++ 0x (as implemented by gcc so far...) if necessary? Ideally I'd want it to be a true ctor for the class so I could use it directly in initialization lists, but a factory function is only slightly less convenient.

Check out what eigen does. They do something similar to nielsm's suggestion, but they overload the comma operator and operator <<. Initializing a matrix (or a vector) looks like this:

code:
Eigen::Matrix<int, 3, 1> vec3;
vec3 << 1, 2, 3;

schnarf
Jun 1, 2002
I WIN.

nielsm posted:

But I don't think those can provide compile-time safety for e.g. a vect3f requiring exactly 3 floats to initialise, as far as I can tell initializer lists only have lengths at runtime.
Correct, eigen gives you a runtime assert.

I can at least say, having used eigen a lot, I'm pretty happy with its initializer syntax for matrices.

schnarf
Jun 1, 2002
I WIN.

Rocko Bonaparte posted:

I think I am having a problem with callbacks across threads and I'm trying to figure out what I might be able to do to fix it. I am using the Irrlicht rendering engine and the Boost C++ libraries, all on Linux. When a series of animations finish a loop, Irrlicht provides a callback system for determining what you might want it to do next. I am trying not to tie up the engine in that callback so I am taking the information from the callback and triggering my own in a separate thread. The receiver of Irrlicht's callbacks lives in a thread separate from Irrlicht's.

I don't want to go about rewriting some stuff in Irrlicht's code to make this all work, but I think it's fair game to put the callback in the same thread as the one running Irrlicht. I might be able to snuff out this problem doing something like that, but now I'm kind of curious because I think I will probably run into this again soon enough.

Also note that I am implementing locks and the locks for a queue of these events; the callback accepts an event and puts it on a queue, where something else chews on it. That all appears to work--it just needs to be triggered from the Irrlicht callback to do one more thing. I started doing this before I realized Irrlicht even had an animation callback, so again I might get away putting the Irrlicht callback in the same thread, etc. Still, now it bothers me that it appears I can't do something like this casually so I want to know what I would have to do if it was the only way.

Edit: FWIW I should add that Irrlicht uses an interface (ie pure virtual functions) for the callbacks, so it's not a problem of passing in a member function when registering the callback initially. It does have C++ awareness here.

What exactly is the problem you're having? Can you please give some more details? Are you saying you're having a problem getting your offloading thread to wake up with it has some data to process? I don't think this is a problem of being "C++ aware," it doesn't sound like this is a C++ problem -- C++ doesn't really know anything about threads. You might run into problems if you are writing or reading any of Irrlicht's data that doesn't expect to be accessed from multiple threads.

A function itself doesn't live in a thread. It's being executed on a thread when it ends up being called *on* that thread. You can pass Irrlicht your own callback in any way you want, and it's going to be executed on whatever thread Irrlicht calls it from.

From what I understand, you're doing this: You have a virtual function A that Irrlicht uses as a callback. When Irrlicht calls A, (on its main thread?), you take that data, and you push it onto a message queue that's being polled by some function B on another thread. That sounds reasonably sane. Be aware that if you're doing this, you don't even need locking. Google "lock-free FIFO." That way you can avoid priority inversion.

schnarf fucked around with this message at 17:36 on Jun 25, 2011

schnarf
Jun 1, 2002
I WIN.
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?

schnarf
Jun 1, 2002
I WIN.
Just get Visual Studio express edition. As far as your error, check the line where you're including the ctype header. You have an extra ""<". Also, in the future, try posting your code with the "code" tags, so that indentation is preserved.

Adbot
ADBOT LOVES YOU

schnarf
Jun 1, 2002
I WIN.
Could you use enable_if and is_base_of to have the templated copy constructor be skipped when T is any class that derives from Base?

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply