This is the mail archive of the
java@gcc.gnu.org
mailing list for the Java project.
RE: performance problem with process fork in gcj compiled CNI
- From: "Boehm, Hans" <hans dot boehm at hp dot com>
- To: "Ricardo Temporal" <ricardotemporal at hotmail dot com>, <java at gcc dot gnu dot org>
- Date: Thu, 26 Jan 2006 11:47:21 -0800
- Subject: RE: performance problem with process fork in gcj compiled CNI
I'm amazed it does anything useful at all.
Once you've created a JVM, your process is multithreaded. The fork()
child only has one of those threads active, and is only allowed to call
async-signal-safe functions until it performs an exec(). (See the SUSV3
spec of fork().) You're not even close to satisfying those
requirements.
Hans
> -----Original Message-----
> From: java-owner@gcc.gnu.org [mailto:java-owner@gcc.gnu.org]
> On Behalf Of Ricardo Temporal
> Sent: Thursday, January 26, 2006 5:11 AM
> To: java@gcc.gnu.org
> Subject: performance problem with process fork in gcj compiled CNI
>
>
> performance problem with process fork in gcj compiled CNI
>
> Hello,
>
> I have a simple C++ program with a main function that
> fork itself's
> process and then it starts a loop calling some processing in
> java compiled
> code, using CNI.
>
> I intend to split processing in a machine with 2 CPUs using fork
> technology, I'm not able to use another solution.
>
> When I run the program without forking, it takes about T
> seconds to
> finish consuming 100% of CPU and 50% of the machine.
>
> When I run the program with a fork in the beginning, it
> takes more than
> 2T seconds to finish with each process consuming 100% of CPU and both
> consuming 100% of the machine.
>
> What's happening ?
>
> Temporal.
>
> #include <iostream>
> #include <string>
> #include <sys/types.h>
> #include <unistd.h>
> #include <gcj/cni.h>
> #include <java/lang/Double.h>
> #include <java/util/ArrayList.h>
>
> using namespace std;
> using namespace java::lang;
> using namespace java::util;
>
> int globalVariable = 2;
>
> /*
> Code Templates:
>
> http://www-personal.umich.edu/~rusekd/articles/soc_prelim.html
> http://www.yolinux.com/TUTORIALS/ForkExecProcesses.html
> */
>
> int main(int argc, char **argv)
> {
> if (argc != 3)
> {
> cerr << "usage: integer bool" << endl;
> return 1;
> }
>
> cout << "begin" << endl;
>
> JvCreateJavaVM(NULL);
> JvAttachCurrentThread(NULL, NULL);
>
> string sIdentifier;
> int iStackVariable = 20;
>
> pid_t pID = (atol(argv[2]) ? fork() : 1);
>
> if (pID == 0) // child
> {
> // Code only executed by child process
>
> sIdentifier = "Child Process: ";
> globalVariable++;
> iStackVariable++;
> }
> else if (pID < 0) // failed to fork
> {
> cerr << "Failed to fork" << endl;
> exit(1);
> // Throw exception
> }
> else // parent
> {
> // Code only executed by parent process
>
> sIdentifier = "Parent Process:";
> }
>
> // Code executed by both parent and child.
>
> cout << sIdentifier;
> cout << " Global variable: " << globalVariable;
> cout << " Stack variable: " << iStackVariable << endl;
>
> ArrayList *arrayList = new ArrayList;
>
> int loopSize = atol(argv[1]);
> int maxArraySize = loopSize >> 3;
>
> for(int i = 0, j = 0; i < loopSize; i++, j++)
> {
> arrayList->add(new Double((jdouble)(double)i));
>
> if (j == maxArraySize)
> {
> j = 0;
>
> jint size = arrayList->size();
>
> arrayList->clear();
>
> cout << pID << ", clear from " <<
> (int)size << " to " <<
> (int)arrayList->size() << endl;
> }
> }
>
> JvDetachCurrentThread();
>
> cout << "end" << endl;
>
> return 0;
> }
>
>
>