JJS wrote:Just want to chime in on the 32 bit vs. 8 bit example. It won't work out to saving memory in reality. The PSP CPU can only access 4 byte aligned memory, this means a 1 byte variable will cost you just as much as a 4 byte variable in terms of memory usage.
But what about arrays? because the GL functions (sceGu(m)DrawArray(), etc) can accept u8 for its (x,y,z) and (u,v) coord, but if it aligns all u8 into u32, I don't see the advantage of using smaller variables anymore...
JJS wrote:Also the -O3 option will actually cost more RAM than -O2 because they cause aggressive loop unrolling and inlining. This might actually make your performance worse because the program doesn't fit in the cache anymore. The PSPs cache is tiny and each instruction is 4 byte long, so it is already crowded in there.
Indeed, you're right, I mixed up the order. -O[0-3] where 0 is optimized for RAM and 3 is optimized for CPU.
JJS wrote:Another thing about C++ vs. C usage on the PSP: Since C++ always passes the this-pointer in a method call it costs performance each time and forces parameter passing on the stack for methods with 4+ parameters (only $a0-$a3 are used for parameters, then it must go through the stack). Also it means more code obviously.
Yes, you're right about the
this pointer, but in some cases, if you have a big enough class, it's better to just pass a 4-byte pointer, rather than 3 INT and a FLOAT, you know? I'd rather do
- Code: Select all
// 1 invisible pointer (4 bytes)
Vertices->Render();
than
- Code: Select all
// 0 invisible pointers, 1 variable (int) and 3 pointers (16 bytes)
Render(qty, vertXYZ, normXYZ, texUV); //considering vertXYZ, normXYZ and texUV are arrays
Theoretically (unless my mind is warped) these 2 codes should be the same:
- Code: Select all
class TestClass
{
public:
int arraySize_;
int *array_;
int strLength_;
char *someString_;
public:
void SetIntArray(int arraySize, int *arr)
{
array_ = new int[arraySize];
for( int i=0; i<arraySize; i++ )
array_[i] = arr[i];
}
void SetString(int strSize, char *str)
{
someString_ = new int[strSize];
for( int i=0; i<strSize; i++ )
someString_[i] = str[i];
}
};
- Code: Select all
struct TestClass
{
int arraySize_;
int *array_;
int strLength_;
char *someString_;
};
void SetIntArray(TestClass *this, int arraySize, int *arr)
{
this->array_ = new int[arraySize];
for( int i=0; i<arraySize; i++ )
this->array_[i] = arr[i];
}
void SetString(TestClass *this, int strSize, char *str)
{
this->someString_ = new int[strSize];
for( int i=0; i<strSize; i++ )
this->someString_[i] = str[i];
}
If I recall, that's the type of interfacing you need to create if you want to use C++ classes in a PRX library. Object-Oriented isn't evil, nor is it a gift from God. It's just another way of categorizing your program into reusable modules. There are advantages (like I mentioned above) and there are disadvantages, as you mentioned. For myself, I use C++ for this reason:
All C is compatible in C++. I can structure my code accordingly so I can figure out what I'm doing, but I also have the wonderful printf() instead of std::cout, you have access to std::string (even though I still use char*, it's fun to be able to append from time to time). In C++, you can make a whole C program without using ANY C++ libraries or classes, but the other way around isn't true.
m0skit0 wrote:SsJVasto wrote:The difference is the PSP's Scheduler is priority-based, and that can be confusing
All OS have priority-based schedulers. PSP's multitasking is preemptive as I said: you have to release the CPU manually. This
is primitive.
I haven't seen this behaviour on PSP... You may be right, and if you are, I must have a fucked up PSP or something... I run in my game engine the Main Thread (runs on its own, started by XMB), turn on the Callbacks thread, turn on the Graphics thread, turn on the Controller thread, then the Music Thread, followed by the Music thread. I don't have to tell them when to play and when not to, and I haven't seen any lag on either of them... I guess the sceGuVBlankStart() (or whatever it's called) must pause the thread for 1/60-(drawing time) seconds, but again, that's not controlled by me. Can you elaborate on this a little? Maybe that's why I'm having random crashes XD