Page 1 of 3

Multi core CPU

Posted: Fri Jun 11, 2010 1:07 am
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

Re: Multi core CPU

Posted: Fri Jun 11, 2010 1:17 am
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.

Re: Multi core CPU

Posted: Fri Jun 11, 2010 9:28 am
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

Re: Multi core CPU

Posted: Fri Jun 11, 2010 10:25 am
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. :?:

Re: Multi core CPU

Posted: Fri Jun 11, 2010 12:26 pm
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.

Re: Multi core CPU

Posted: Fri Aug 06, 2010 2:19 am
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

Re: Multi core CPU

Posted: Fri Aug 06, 2010 4:09 am
by skiman
Maybe the following?

#include "dll.ch"

Re: Multi core CPU

Posted: Mon Aug 09, 2010 7:49 pm
by STLau
DLL.ch is already included, otherwise error is 'unknown variable dll_cdecl'.
The error is function not declared for 'DllprepareCall'.

regards

Re: Multi core CPU

Posted: Tue Aug 10, 2010 4:25 am
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.

Re: Multi core CPU

Posted: Tue Aug 10, 2010 7:45 pm
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