[phpBB Debug] PHP Warning: in file [ROOT]/ext/tas2580/privacyprotection/cron/task/anonymize_ip.php on line 83: A non-numeric value encountered Feststellen Anzahl CPUs - Inoffizielles deutsches Xbase-Forum
Inoffizielles deutsches Xbase-Forum
Das deutschsprachige Forum für Entwickler in der Xbase-Welt, ein Angebot des Deutschsprachige Xbase-Entwickler e. V.
FUNCTION CHECKMaxCPU()
LOCAL nStep, r
LOCAL nMaxCPU
nStep := 1
DO WHILE .T.
nMaxCPU = 2 ^nStep
IF (r:=SmpSetCPU(nMaxCPU)) = 0
EXIT
ENDIF
nStep++
ENDDO
RETURN nStep
Bei einem Kunden läuft die Funktion auf einen Fehler, da dort scheinbar mehr als 32 CPUs vorhanden sind.
Gibt es noch einen anderen Weg, die Anzahl festzustellen ?
@Christian,
da wird dasselbe Problem auftauchen, da 2^32 das Ende bei 32bit ist.
Ich denke, ich werde die Schleife einfach bei step=32 abbrechen.
Oder ich nehme gleich DC_SetCPU() von eXPress++
wenn du NUR für internes Schalten was brauchst ist die Begrenzung auf 32 Prozessoren sicher sinnvoll.
Ansonsten sollte MSI aber schon den richtigen Wert ermitteln können ...
Terminal Server. Mehrere App-Instanzen laufen für mehrere Benutzer auf dem selben System. Da sich Xbase++-Anwendungen standardmäßig Prozessor 1 greifen, hätte man nach vier oder fünf Anmeldungen die volle Last auf Prozessor 1, während 3, 7, 15, 31 oder 63 weitere Prozessoren leerlaufen würden. Also wählt man - erfahrungsgemäß am besten zufällig - beim Applikationsstart irgendeinen der verfügbaren Kerne aus. Wer will, erlaubt zusätzlich die Umschaltung direkt im Programm.
Die "Terminal-Server-Software" wäre das Betriebssystem. Windows kann Applikationen zwar Prozessoren zuweisen, aber Xbase++ unterbindet das seit Version 1.7 explizit - Steffen hatte irgendwann auch mal erklärt, warum. Seither schnappt sich eine Xbase++-Applikation standardmäßig Prozessor #1. Da man relativ simpel zwischen CPUs umschalten kann, stellt sich in diesem Kontext lediglich die Frage, auf Basis welcher Parameter man das tut - tun sollte man es in jedem Fall, wenn die Applikation auf einem Terminal Server läuft. Erfahrungsgemäß fährt man nach dem Zufallsprinzip am besten. Versuche, die Prozessorlasten zu ermitteln oder über irgendwelche Überwachungsfunktionen gleichmäßig zu verteilen, scheitern daran, dass die Prozessorlast weniger davon abhängt, wie viele Instanzen einer Software laufen, sondern was diese derzeit tun.
wie Hubert sagte würde ich es mit WMI versuchen die CPU Anzahl zu ermitteln ... aber wie willst du dann "umschalten" auf > CPU 32 ?
was wir benötigen ist ein 64bit Xbase++ !!!
Das dürfte mit Pablos OT4XB gehen. Das Problem bei DLL-Calls in/aus Xbase++-Anwendungen ist, dass die Datentypen "geshreddert" werden, was selbst dann gilt, wenn man es geschafft hat, irgendwie z.B. 64-Bit-Integer zu generieren. OT4XB beherrscht sämtliche Datentypen und kann auch eigene DLL-Calls generieren, bei denen die Typen erhalten bleiben (nFpCall).
wie Hubert sagte würde ich es mit WMI versuchen die CPU Anzahl zu ermitteln
Da gibt's auch API-Funktionen für - _sysSetCPU verwendet sie vermutlich (KERNEL32.DLL). Ich suche morgen mal. Und es endet ohnehin bei 64 Prozessoren - ab da werden Prozessorgruppen verwaltet.
Tom hat geschrieben:Da gibt's auch API-Funktionen für - _sysSetCPU verwendet sie vermutlich (KERNEL32.DLL).
die Function heisst "SetProcessAffinityMask" welches ein DWORD erwartet.
On a system with more than 64 processors, the SetProcessAffinityMask function can be used to set the process affinity mask only for processes with threads in a single processor group. Use the SetThreadAffinityMask function to set the affinity mask for individual threads in multiple groups. This effectively changes the group assignment of the process.
function CountProcessors
local si := SYSTEM_INFO():new()
@kernel32:GetSystemInfo(si)
return si:dwNumberOfProcessors
BEGIN STRUCTURE SYSTEM_INFO
MEMBER DWORD dwOemId
MEMBER DWORD dwPageSize
MEMBER POINTER lpMinimumApplicationAddress
MEMBER POINTER lpMaximumApplicationAddress
MEMBER POINTER dwActiveProcessorMask
MEMBER DWORD dwNumberOfProcessors
MEMBER DWORD dwProcessorType
MEMBER DWORD dwAllocationGranularity
MEMBER WORD wProcessorLevel
MEMBER WORD wProcessorRevision
END STRUCTURE
zu Thema "setzen" einer CPU hab ich noch das gefunden
Was für ein Prozessor, das kann ich dir leider auch nicht sagen.
Die Prozessoranzahl ist mir eigentlich nicht so wichtig, DC_SetCPU begrenzt aber das Abfragen auf 32bit.
Und vielleicht läuft ja auch jemand anders, der diese Begrenzung nicht beachtet, mal auf diesen Fehler (Christians Routine beachtet das auch nicht).
wenn die API eine DWORD Var vorsieht, UND jedes Bit für 1 Prossor Ja/Nein steht, kann diese auch nicht mehr ansteuern.
"Normales" Windows kann meines Wissens auch nur deutlich weniger.
ABER eine Funktion, die so auf die Bits zugreift, MUSS sich auch um die Grenzen kümmern, sonst ist es eine tickende Zeitbombe ...
function CountProcessors
local si := SYSTEM_INFO():new()
@kernel32:GetSystemInfo(si)
return si:dwNumberOfProcessors
BEGIN STRUCTURE SYSTEM_INFO
MEMBER DWORD dwOemId
MEMBER DWORD dwPageSize
MEMBER POINTER lpMinimumApplicationAddress
MEMBER POINTER lpMaximumApplicationAddress
MEMBER POINTER dwActiveProcessorMask
MEMBER DWORD dwNumberOfProcessors
MEMBER DWORD dwProcessorType
MEMBER DWORD dwAllocationGranularity
MEMBER WORD wProcessorLevel
MEMBER WORD wProcessorRevision
END STRUCTURE
zu Thema "setzen" einer CPU hab ich noch das gefunden