-lpsplibc -lc or "Do not cross the streams Venkman"

Discuss the development of new homebrew software, tools and libraries.

Moderators: cheriff, TyRaNiD

Post Reply
Panajev2001a
Posts: 100
Joined: Sat Aug 20, 2005 3:25 am

-lpsplibc -lc or "Do not cross the streams Venkman"

Post by Panajev2001a »

Hi everyone.

I am building an application all in C++ using PSPSDK and I started with the reflection sample as sort of framework, spawning my separate sample in its own directory but still (for now) rendering the same things reflections renders to make sure the classes I port to it do not make crash what I know to be a fully working application (a solid benchmark point).

I use obviously build.mak (modified in one line to allow g++ to do the linking else it won't link and saved as build1.mak so future updates of PSPSDK do not overwrite it) and before including it in the Makefile I set my libs for the application.

LIBS= -lpsplibc -lstdc++ -lc -lpspgu -lg -lintmdloader -lgeommath -lm

Yes, Mr. Brown I am crossing the streams ;).

You know what is funny though ? If I take out -lpsplibc the program will compile and link, but also crash once you start it on the PSP: it passes the splash screen, it loads the code and game art assets, the screen stays dark and then the PSP turns itself off.

If I leave -lpsplibc in the program will compile and link, but not crash once you start it on PSP: it loads my pmatrix, point and intmd-related objects and reads into the CSceneCreatorIntmd object my scene geometry (which for the moment is not rendered, I have to port the code I used to read from the CSceneCreatorIntmd file and render, obviously I will not use GIF and VIF tags on PSP ;)) and it renders the cube with its reflection as we all know and love.

Does it seem something normal to you all ?
mrbrown
Site Admin
Posts: 1537
Joined: Sat Jan 17, 2004 11:24 am

Post by mrbrown »

Hmm. One thing we've noticed is that when using psp-g++ to link, it will rearrange the library order to make sure -lc appears before -lstdc++. Matter of fact, the -lstdc++ in your LIBS is redundant, as psp-g++ will insert it. psp-g++ will also strip the first -lc it finds and place it at the end of the library list. This causes problems in build.mak because we assume -lc will appear before -lpspuser.

You shouldn't have to link with both -lpsplibc and -lc, which makes me think it's psp-g++ that's screwing things up. Try removing -lpsplibc and -lstdc++ from LIBS, and add a second -lc to workaround psp-g++ removing the first -lc.

Or, keep doing what you're doing but use psp-gcc to link and make sure that library dependencies are satisfied in the LIBS line. Basic rule when using the braindead GNU linker: libraries must appear before the libraries they depend on. So your LIBS would work out to be:

Code: Select all

LIBS = -lintmdloader -lgeommath -lpspgu -lstdc++ -lm -lc
BTW -lg == -lc so you will want to get rid of that too.
Panajev2001a
Posts: 100
Joined: Sat Aug 20, 2005 3:25 am

Post by Panajev2001a »

mrbrown wrote:Hmm. One thing we've noticed is that when using psp-g++ to link, it will rearrange the library order to make sure -lc appears before -lstdc++. Matter of fact, the -lstdc++ in your LIBS is redundant, as psp-g++ will insert it. psp-g++ will also strip the first -lc it finds and place it at the end of the library list. This causes problems in build.mak because we assume -lc will appear before -lpspuser.

You shouldn't have to link with both -lpsplibc and -lc, which makes me think it's psp-g++ that's screwing things up. Try removing -lpsplibc and -lstdc++ from LIBS, and add a second -lc to workaround psp-g++ removing the first -lc.

Or, keep doing what you're doing but use psp-gcc to link and make sure that library dependencies are satisfied in the LIBS line. Basic rule when using the braindead GNU linker: libraries must appear before the libraries they depend on. So your LIBS would work out to be:

Code: Select all

LIBS = -lintmdloader -lgeommath -lpspgu -lstdc++ -lm -lc
BTW -lg == -lc so you will want to get rid of that too.
Ok, I am now using gcc to link instead of g++ and I replaced my LIBS with your LIBS (I got the order of some libs wrong, thansk for the help there...).

It compiles and it runs on the PSP.

This is the Makefile now:

Code: Select all

TARGET = reflection
OBJS = src/reflection.o src/disablefpu.o logo.o src/point.o src/pmatrix.o

INCDIR =
CFLAGS = -G0 -Wall -Os -msingle-float -funroll-loops -ffast-math -fsingle-precision-constant -fno-exceptions
CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti
ASFLAGS = $(CFLAGS)

LIBDIR =
LDFLAGS = 
LIBS= -lintmdloader -lgeommath -lpspgu -lstdc++ -lm -lc 


EXTRA_TARGETS = EBOOT.PBP
PSP_EBOOT_TITLE = Reflection Sample


PSPSDK=$(shell psp-config --pspsdk-path)
include $(PSPSDK)/lib/build.mak


logo.o: ../gu/cube/logo.raw
	bin2o -i $< logo.o logo
I am trying to use -Os and some other compiler flag to get a good compromise between size and speed (taking also the DCache into account and the fact that although there is 2x the L1 DChache compared to the EE now Main RAM is about 2x the latency for a miss compared to the EE).

I checked on the GCC 4.0.1 manuals which flags were enabled by default with -Os and which flags were disabled by -Os so that I would remember not to enable those.
holger
Posts: 204
Joined: Thu Aug 18, 2005 10:57 am

Post by holger »

"-Os" and "-funroll-loops" don't make much sense in combination. Rather try e.g. "-ffunction-sections" and friends, so that unused code sections can get stripped out.
Panajev2001a
Posts: 100
Joined: Sat Aug 20, 2005 3:25 am

Post by Panajev2001a »

holger wrote:"-Os" and "-funroll-loops" don't make much sense in combination. Rather try e.g. "-ffunction-sections" and friends, so that unused code sections can get stripped out.
It is true that loop unrolling increases code size, but -Os does not disable it by default: -Os already disables several -O2 optimizations that tend to increase code size, but this is not one of them.
-Os
Optimize for size. -Os enables all -O2 optimizations that do not typically increase code size. It also performs further optimizations designed to reduce code size.

-Os disables the following optimization flags:

-falign-functions -falign-jumps -falign-loops
-falign-labels -freorder-blocks -freorder-blocks-and-partition -fprefetch-loop-arrays
http://gcc.gnu.org/onlinedocs/gcc-4.0.1 ... ze-Options

Loop unrolling is not enabled by -O2 nor -O1.

It is one of the compromises between speed and cache friendly code size reduction I mentioned in my post earlier: being ALLEGREX not a register starved, though in-order core with not so close main RAM (~70 cycles away and even if you use SPRAM you are talking about 35-40 cycles almost) loop unrolling might help tight loops to be less stall-prone (this flag does not affect all loops).

A lot of people go with -O2 as they feel the code expansion is not as bad as renouncing to some of the optimizations -O2 carries with it: I went for -Os to help Cache, but I think that the lack of loop unrolling might worsen performance (-O2 and loop-unrolling might place a bit too much stress on the cache). Loop-unrolling does potentially worsen Icache hits, but it helps reducing the impact of a relatively high main RAM latency.

Thanks for the suggestion about -ffunction-sections
-fdata-sections: this is something I will try when doing the final optimization pass as these options might help as much as they might worsen performance (slower and larger executables) although they improove locality of reference for the instructions thus helping the Icache.

Edit: After thinking more about it, I will definately try it with loop-unrolling and without.

Please apologize if I sound rude or know-it-all, I do not mean it and I am neither of those (I just try to show that I have done some sort of research and put some thought behind my actions not to teach anyone, especially one of PSPSDK's writers :)) and I appreciate everyone's input :).
holger
Posts: 204
Joined: Thu Aug 18, 2005 10:57 am

Post by holger »

Panajev2001a wrote:
holger wrote:"-Os" and "-funroll-loops" don't make much sense in combination. Rather try e.g. "-ffunction-sections" and friends, so that unused code sections can get stripped out.
It is true that loop unrolling increases code size, but -Os does not disable it by default: -Os already disables several -O2 optimizations that tend to increase code size, but this is not one of them.
see below...

Panajev2001a wrote:
-Os
Optimize for size. -Os enables all -O2 optimizations that do not typically increase code size. It also performs further optimizations designed to reduce code size.

-Os disables the following optimization flags:

-falign-functions -falign-jumps -falign-loops
-falign-labels -freorder-blocks -freorder-blocks-and-partition -fprefetch-loop-arrays
http://gcc.gnu.org/onlinedocs/gcc-4.0.1 ... ze-Options

Loop unrolling is not enabled by -O2 nor -O1.
That's the reason why it is not listed in the "disable-list", there is no need to disable options that are not enabled...

Panajev2001a wrote:It is one of the compromises between speed and cache friendly code size reduction I mentioned in my post earlier: being ALLEGREX not a register starved, though in-order core with not so close main RAM (~70 cycles away and even if you use SPRAM you are talking about 35-40 cycles almost) loop unrolling might help tight loops to be less stall-prone (this flag does not affect all loops).
Try the __likely()/__unlikely() tags instead (simply put them around your loop conditions and if-conditions for assertions). They prevent stalling in the common code path and don't increase the code.

Holger
webjeff
Posts: 66
Joined: Thu May 05, 2005 2:51 am

Post by webjeff »

Panajev2001a,

I'm in the same situation as you. As of right now, here's what I have found out about C++ and pspgl:

you need to have "USE_PSPSDK_LIBC = 1" in your makefile specifying using psplibc NOT libc. not sure exactly why, but whenever I am using libc, pspgl doesn't initialize and c++ does really weird things, corrupting memory weird things.

However, my application is getting undefined errors to:

Code: Select all

/usr/local/pspdev/lib/gcc/psp/4.0.1/../../../../psp/lib/libstdc++.a&#40;pure.o&#41;&#58;../.
./../../libstdc++-v3/libsupc++/pure.cc&#58;54&#58; undefined reference to `write'
/usr/local/pspdev/lib/gcc/psp/4.0.1/../../../../psp/lib/libstdc++.a&#40;vterminate.o
&#41;&#58;../../../../libstdc++-v3/libsupc++/vterminate.cc&#58;69&#58; undefined reference to `_
impure_ptr'
/usr/local/pspdev/lib/gcc/psp/4.0.1/../../../../psp/lib/libstdc++.a&#40;vterminate.o
&#41;&#58;../../../../libstdc++-v3/libsupc++/vterminate.cc&#58;70&#58; undefined reference to `_
impure_ptr'
/usr/local/pspdev/lib/gcc/psp/4.0.1/../../../../psp/lib/libstdc++.a&#40;vterminate.o
&#41;&#58;../../../../libstdc++-v3/libsupc++/vterminate.cc&#58;74&#58; undefined reference to `_
impure_ptr'
/usr/local/pspdev/lib/gcc/psp/4.0.1/../../../../psp/lib/libstdc++.a&#40;vterminate.o
&#41;&#58;../../../../libstdc++-v3/libsupc++/vterminate.cc&#58;74&#58; undefined reference to `_
impure_ptr'
/usr/local/pspdev/lib/gcc/psp/4.0.1/../../../../psp/lib/libstdc++.a&#40;vterminate.o
&#41;&#58;../../../../libstdc++-v3/libsupc++/vterminate.cc&#58;51&#58; undefined reference to `_
impure_ptr'
/usr/local/pspdev/lib/gcc/psp/4.0.1/../../../../psp/lib/libstdc++.a&#40;vterminate.o
&#41;&#58;../../../../libstdc++-v3/libsupc++/vterminate.cc&#58;51&#58; more undefined references
 to `_impure_ptr' follow
collect2&#58; ld returned 1 exit status
make&#58; *** &#91;DisplayClient.elf&#93; Error 1
I talked with Tyranid on IRC and it seems psplibc is not fully complete and seems to be missing some definitions.

I have tried to add them myself, but being unfamiliar with gcc, this seems a little more complicated than I had hoped. Can anyone assist me and everyone else by defining these items so we can link with psplibc instead of libc?

Thanks everyone
Jeff.
mrbrown
Site Admin
Posts: 1537
Joined: Sat Jan 17, 2004 11:24 am

Post by mrbrown »

Trust me, you want to use libc and not psplibc. Now back to libc, can you be more specific about the problems you encountered?
holger
Posts: 204
Joined: Thu Aug 18, 2005 10:57 am

Post by holger »

I still like the idea of a very minimal native libc implementation, do you want to stop working on it?
Panajev2001a
Posts: 100
Joined: Sat Aug 20, 2005 3:25 am

Post by Panajev2001a »

holger wrote:I still like the idea of a very minimal native libc implementation, do you want to stop working on it?
Suggestion: full, native libc implementation ;).
holger
Posts: 204
Joined: Thu Aug 18, 2005 10:57 am

Post by holger »

well... the psplibc already has almost everything you usually need...
mrbrown
Site Admin
Posts: 1537
Joined: Sat Jan 17, 2004 11:24 am

Post by mrbrown »

holger wrote:I still like the idea of a very minimal native libc implementation, do you want to stop working on it?
holger wrote:well... the psplibc already has almost everything you usually need...
There is nothing inherently native about psplibc - the backend calls to the OS are the same in both psplibc and newlib libc.

Besides that the authors of psplibc have already stated that it was never intended to be complete, and that folks needing a complete libc should link against newlib's libc.
webjeff
Posts: 66
Joined: Thu May 05, 2005 2:51 am

Post by webjeff »

Mr. brown,

Can you confirm to me that you think its best when working in C++ NOT to use "USE_PSPSDK_LIBC = 1" meaning not linking with psplibc?

I also noticed pspgl requires it, I cannot initialize a surface without linking with that library, even in the egl example, I know its not part of the sdk, but if that doesn't work then I'm really confused.

Jeff.
skeezixcodejedi
Posts: 29
Joined: Tue Aug 30, 2005 10:37 am
Contact:

Post by skeezixcodejedi »

I suspect I had a related problem..

Simple code in one or more .o files was working with a more-or-less typical PSPSDK Makeflie; -l pspgu was added to the defaults, and otherwise the same.. and she worked.

I added in 10 or 15 source files from one of the projects I'm porting over.. compiled out of the box, but linking produced an _impure_ptr linking error. (Never seen that before, after a lot of years of development across numerous platforms :)

Tried swapping libs as above and the PSP always crashed.. with or without the Makefile USE_PSPSDK_LIBC being set or commented out.

In the end I removed a fprintf and used the default libs and the thing ran again.

So I'm not really use which libs to use.. the defaults for PSPSDK seem more or less to work, but bringinging in anything else seems to bugger it all up :)

jeff
--
Have you played Atari today?
Post Reply