Multi core CPU

This forum is for eXpress++ general support.
Message
Author
STLau
Posts: 11
Joined: Mon Feb 08, 2010 11:35 pm

Multi core CPU

#1 Post by STLau »

I am using RDP ( remote desktop ) to run xbase++ program. However, the exe does not take advantage on the multi core CPU.
I have to manually assign each EXE to run on a specific core. Most other program automatically run on multiple core.
Can anyone advise how to make xbase exe run on multi-core?

Regards

User avatar
Tom
Posts: 1173
Joined: Thu Jan 28, 2010 12:59 am
Location: Berlin, Germany

Re: Multi core CPU

#2 Post by Tom »

Hi, Stu.

Xbase++ programs are not able to run on multiple CPUs at the same time. By default, they select CPU #1 to run on. You can switch the core for each instance of your application by using "_sysSetCPU" from the XppRt1-lib of your Alaska installation (..\Source\Samples\Solution\smp). This works anytime you want from inside the app. As I found out (and I'm not the only one), the best way to do this is to create a random number based on the number of available CPUs. All other systems (like getting the CPU usage from the Windows WMI system) are not very reliable. Another way is to create a table with all instances of the app running and selecting the next free/least used CPU. If you have a limited number of workstations, it might be an idea to set the CPU using an app parameter.
Best regards,
Tom

"Did I offend you?"
"No."
"Okay, give me a second chance."

User avatar
rdonnay
Site Admin
Posts: 4733
Joined: Wed Jan 27, 2010 6:58 pm
Location: Boise, Idaho USA
Contact:

Re: Multi core CPU

#3 Post by rdonnay »

Here is a function that will automatically select a different CPU for each instance of the application.
This has been tested on several Terminal Server and Citrix Server applications.

nCpu should be 15 (default) for 4 CPUs.
cFile is a pointer to the semaphore file that is created. It keeps track of the last CPU assigned.

Code: Select all

FUNCTION DC_SetCPU( nCPU, cFile )

LOCAL nHnd  := 0                             // file handle
LOCAL nLast := 1                             // last CPU used
LOCAL aSet  := {}                            // processor array
LOCAL nSet                                   // default new bitmask
LOCAL i                                      // counter

DEFAULT cFile := GetEnv('WINDIR') + '\Temp\SetCpu.Smp'

DEFAULT nCPU := 15
//  7 = 3 CPUs
//  3 = 2 CPUs
//  1 = 1 CPU

nSet := nCPU

FOR i := 1 to 32                             // count processors
   IF nCPU[i]                                // processor present
      aadd(aSet, i)                          // add processor id to list
   ENDIF
NEXT

IF len(aSet) > 1                             // more then one processor
   IF Fexists(cFile)
      nHnd := Fopen(cFile, FO_READWRITE)
      IF nHnd > 0                            // file is open
         nLast := Val(Freadstr(nHnd, 2))+ 1  // get last processor
         IF nLast > len(aSet)                // check against available processors
            nLast := 1                       // recycle number
         ENDIF
         Fseek(nHnd, 0, FS_SET)              // place pointer at bof
         Fwrite(nHnd, StrZero(nLast, 2))     // write to file
         Fclose(nHnd)                        // close file
      ENDIF
   ELSE                                      // first time round
      nHnd := Fcreate(cFile, FC_NORMAL)
      IF nHnd > 0                            // file is created and open
         Fwrite(nHnd, StrZero(nLast, 2))     // write to file
         Fclose(nHnd)                        // close file
      ENDIF
   ENDIF

   FOR i := 1 to 32                          // create new bitmask
      nSet[i] := (i = aSet[nLast])           // switch on appropriate bit
   NEXT

   DllCall("xpprt1.dll", DLL_CDECL, "_sysSetCPU", nSet)

ENDIF

RETURN nil
The eXpress train is coming - and it has more cars.

skiman
Posts: 1185
Joined: Thu Jan 28, 2010 1:22 am
Location: Sijsele, Belgium
Contact:

Re: Multi core CPU

#4 Post by skiman »

Hi ROger,

I'm trying to understand this piece of code.

Code: Select all

FOR i := 1 to 32                             // count processors
   IF nCPU[i]                                // processor present
      aadd(aSet, i)                          // add processor id to list
   ENDIF
NEXT
if nCPU ... : when will that be .T. :?:
Best regards,

Chris.
www.aboservice.be

User avatar
rdonnay
Site Admin
Posts: 4733
Joined: Wed Jan 27, 2010 6:58 pm
Location: Boise, Idaho USA
Contact:

Re: Multi core CPU

#5 Post by rdonnay »

I copied this code from a customer app that I wrote several years ago and decided it would be a good idea to add it to eXpress++. I think I copied something wrong. I didn't get a chance to test it. I'll look at it again when I get back to the office.

Ok, it appears that nCPU is a bit test. You will get a different result if you set nCPU to 1, 3, or 7.
The eXpress train is coming - and it has more cars.

STLau
Posts: 11
Joined: Mon Feb 08, 2010 11:35 pm

Re: Multi core CPU

#6 Post by STLau »

Hi

After adding the function SMPGETCPU(), I encounter a runtime error function not declared for 'DllPrepareCall'. May I know what else do I need to link?

Thanks

skiman
Posts: 1185
Joined: Thu Jan 28, 2010 1:22 am
Location: Sijsele, Belgium
Contact:

Re: Multi core CPU

#7 Post by skiman »

Maybe the following?

#include "dll.ch"
Best regards,

Chris.
www.aboservice.be

STLau
Posts: 11
Joined: Mon Feb 08, 2010 11:35 pm

Re: Multi core CPU

#8 Post by STLau »

DLL.ch is already included, otherwise error is 'unknown variable dll_cdecl'.
The error is function not declared for 'DllprepareCall'.

regards

User avatar
Tom
Posts: 1173
Joined: Thu Jan 28, 2010 12:59 am
Location: Berlin, Germany

Re: Multi core CPU

#9 Post by Tom »

You have a typo in there. "DLL_CDECL" is a constant from DLL.CH and should be replaced by the preprocessor at compile time. If this is not done, you mabye typed lower case letters (they have to be upper case) or added something by mistake (like "()"). Take a look at the ppo-output (XPP myfile.prg /P). There should be the number '8' instead of something like "DLL_CDECL". If you want, you can replace "DLL_CDECL" with this number and remove the include-file, but this is not very elegant.
Best regards,
Tom

"Did I offend you?"
"No."
"Okay, give me a second chance."

STLau
Posts: 11
Joined: Mon Feb 08, 2010 11:35 pm

Re: Multi core CPU

#10 Post by STLau »

Thanks Tom.

The error is function not defined. Nothing to do with the variable in DLL.ch. I don't know where is the function 'DllprepareCall'. In which library and why is it not defined if it is part of the system library.

regards

Post Reply