infowars
Goto Top

Win7 Zugehörigkeit Prozessorkerne

Moin,
ich versuche einen oder mehrere Prozesse mit allen Kernen zu starten.
Das klappt aber nicht. Ich habe auch schon Tools wie GnSAffinity und TaskAssign runtergeladen, aber auch mit denen will es einfach nicht.
Zuletzt habe ich so versucht die Prozesse über eine Kommando-Box mit mehr als nur einem Kern zu starten:

C:\Windows\System32\cmd.exe /C START "GTR2" /affinity 10 "X:\Program Files (x86)\SimBin\GTR 2\GTR2.exe"
C:\Windows\System32\cmd.exe /C START "GTR2" /affinity 10 "X:\Program Files (x86)\SimBin\GTR 2\GTR2Dedicated.exe"

Aber auch so wird der Prozess nur mit einem Kern gestartet. Der Rechner ist ein Win7 mit 64bit und einem 4-Kern AMD Phenom II.

Gibt es jemanden der dieses Problem schon hatte und es lösen konnte ?

MfG

Content-ID: 187451

Url: https://administrator.de/contentid/187451

Ausgedruckt am: 22.11.2024 um 05:11 Uhr

Penny.Cilin
Penny.Cilin 04.07.2012 aktualisiert um 10:16:32 Uhr
Goto Top
Moin,

1. Frage: Ist die Anwendung Mehrprozessorfähig, d. h. nutzt diese auch mehrere Prozesoren?
2. Frage: Was bezweckst Du damit, eine Anwenung gleich auf mehrere Prozessoren zu starten? Lass es doch das Betriebssystem bzw. der Anwendung entscheiden.

Außerdem mußt Du beimParameter /Affinity den Wert in Hex angeben also /Affinity 0x3 z. Beispiel.


Gruss Penny
infowars
infowars 04.07.2012 aktualisiert um 10:42:13 Uhr
Goto Top
1. Ja, ich muss z.Z. immer manuell die Zugehörigkeit auf alle Kerne verteilen, da die CPU-Auslastung des 1.Kerns sonst permanent zu 100 % ausgelastet ist.
2. Win7 startet den Prozess immer nur mit CPU 0, die benötigte CPU-Power ist jedoch viel höher. Kann ja mal ein Bild mit der Auslastung postenface-smile

Das mit dem Hex-Wert hab ich da gelesen:
http://www.cosmiq.de/qa/show/3284930/Wie-kann-ich-bei-Win7-die-4-Kerne- ...

Hab mit dem Hex-Wert auch schon rumgespielt,egal ob 0x10 oder 10, der Prozess startet immer nur mit einem Kern.
Penny.Cilin
Penny.Cilin 04.07.2012 um 10:58:32 Uhr
Goto Top
Zitat von @infowars:

C:\Windows\System32\cmd.exe /C START "GTR2" /affinity 10 "X:\Program Files (x86)\SimBin\GTR 2\GTR2.exe"
C:\Windows\System32\cmd.exe /C START "GTR2" /affinity 10 "X:\Program Files (x86)\SimBin\GTR
2\GTR2Dedicated.exe"

Abre wenn ich den Pfad sehe, dann ist es eine 32bit Anwendung. Und ist diese Mehrprozessorfägig? Um welche Anwendung handelt es sich?

Gruss Penny
infowars
infowars 04.07.2012 aktualisiert um 11:25:10 Uhr
Goto Top
Das ist ein Rennspiel für den PC namens GTR2.
Sobald jemand auf dem dedizierten Server spielt, schiesst die CPU-Last nach oben.
Je mehr Spieler mitfahren, desto höher die CPU-Last.
Bei manuellem Einstellen der Zugehörigkeit verteilt sich die Last schön gleichmässig auf alle Kerne.
Wird beim Start des dedizierten Servers vergessen die Zugehörigkeit auf alle Kerne einzustellen ruckelt das Spiel grausig.
Wenn dann grad kein Admin da ist, ist das doof.
Gruss zurück.
SlainteMhath
SlainteMhath 04.07.2012 um 11:27:57 Uhr
Goto Top
Moin,

Hab mit dem Hex-Wert auch schon rumgespielt,egal ob 0x10 oder 10,
10 dezimal ist 0xA in Hex, aber das nur nebenbei.

Du kannst keine Applikation "auf allen Kernen starten". Entweder das Programm ist Mehrkern/Multithreading fähig oder nicht.

Was du mach kannst: Programm 1 auf CPU0 laufen lassen, Programm 2 auf CPU1 und Program 3 auf CPU2 - das ist auch genau das was der /affinity Schalter bewirkt.

lg,
Slainte
infowars
infowars 04.07.2012 aktualisiert um 11:46:50 Uhr
Goto Top
Zitat von @SlainteMhath:
Hab mit dem Hex-Wert auch schon rumgespielt,egal ob 0x10 oder 10,
10 dezimal ist 0xA in Hex, aber das nur nebenbei.
Hab ich auch schon probiert, der Prozess startet nur auf CPU0.
Zitat von @SlainteMhath: Du kannst keine Applikation "auf allen Kernen starten". Entweder das Programm ist Mehrkern/Multithreading fähig
oder nicht.
Wenn ich manuell die Zugehörigkeit festlege, ruckelt aber das Spiel nicht mehr.
Zitat von @SlainteMhath:Was du mach kannst: Programm 1 auf CPU0 laufen lassen, Programm 2 auf CPU1 und Program 3 auf CPU2 - das ist auch genau das was der
/affinity Schalter bewirkt.
Dann muss das doch auch irgendwie für mehrere Kerne gehen, behauptet jedenfalls der da:
http://www.cosmiq.de/qa/show/3284930/Wie-kann-ich-bei-Win7-die-4-Kerne- ...
Zitat :
/affinity 3 (nimmt cpu 0 + 1)
Penny.Cilin
Penny.Cilin 04.07.2012 aktualisiert um 12:29:42 Uhr
Goto Top
Weil seine Anwendung vielleicht Mehrprozessor/Mehrkernfähig ist?.
Nur weil ein Anwender eine Anwendung auf mehrere Prozessoren/Kernen verteilen kann, heißt nicht das es bei JEDER Anwendung geht.

Prüfe doch erstmal, ob DEINE Anwendung Mehrkern/Multithreading überhaupt unterstützt.

Wenn Deine Anwendung Mehrkern/Multithreading NICHT unterstützt, wird es auch nicht funktionieren - Basta.

Gruss Penny
SlainteMhath
SlainteMhath 04.07.2012 um 12:39:34 Uhr
Goto Top
0xA ... Hab ich auch schon probiert, der Prozess startet nur auf CPU0.
So eben mal nachgelsesen. /affinity erwartet eine DEZIMAL Zahl, die als Bitmaske für die zu verwendenten CPU Kerne interprtiert wird:
CPU0 = 1
CPU1 = 2
CPU3 = 4
CPU4 = 8

Alle zu verwendenten Kerne müssen zusammen gezählt werden. CPU0+CPU1 = 1+2 = 3 oder CPU2+CPU4 = 4+8 = 12

Dann muss das doch auch irgendwie für mehrere Kerne gehen, behauptet jedenfalls der da:
Ja die Sprechen da auch von dem Programm Blender - das ist ein Reaytracing Renderer der Multithrading unterstützt.

Wenn Deine Anwendung Mehrkern/Multithreading NICHT unterstützt, wird es auch nicht funktionieren - Basta.
Genau!
infowars
infowars 04.07.2012 aktualisiert um 13:01:53 Uhr
Goto Top
So, nochmal nachgelesen, GTR2 ist definitiv Multicore-fähig, startet standardmässig aber nur mit einem Kern.
Penny.Cilin
Penny.Cilin 04.07.2012 aktualisiert um 13:34:23 Uhr
Goto Top
Dann schau mal hier:

link1 oder link2

oder nutze google suche

Es scheint hier widersprüchliche Aussagen zu geben.
infowars
infowars 04.07.2012 aktualisiert um 15:26:11 Uhr
Goto Top
Bin auch grad soweit, dass ich jetzt mit dem Auto-Updater Einstellungen vornehme, die es sonst nicht (offen) gibt.
Frage mich nur gerade:
Wenn die es mit einem Tool schaffen muss es ja einen Weg geben.
What ever, ich klemme mich mal dahinter und poste dann das Ergebnis:

EDIT:
Die Verknüpfung, die angelegt wird sieht dann so aus:
C:\Python27\pythonw.exe "C:\Pfad\Bierbuden Autoupdate\cpuaffinity.py" --cpuid=0,1,2,3 "u:\Program Files (x86)\SimBin\GTR 2\GTR2.exe"

Und damit funktionierts !!!
Muss mich wohl mal mit Python beschäftigen.
Danke an alle Antworten !
MfG


Hier noch der Code:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# $Id: cpuaffinity.py 770 2011-10-19 21:00:15Z Stef $
# Copyright (C) 2011 Stefan Schwendeler ( kungpfui@gmail.com )

""" Set CPU affinity and process priority of a new process. """  

__version__ = u'$Revision: 770 $'  
__author__ = u'Stefan Schwendeler'  

import os, sys
import optparse
import multiprocessing
import time
from ctypes import *


check_interval	= 5.0
validation_nb	= 12


# some constants of windows os
priorities = {
	'low':			0x00000040,  
	'below_normal':	0x00004000,  
	'normal':		0x00000020,  
	'above_normal':	0x00008000,  
	'high':			0x00000080,  
	'realtime':		0x00000100,  
}


BYTE      = c_ubyte
WORD      = c_ushort
DWORD     = c_ulong
DWORD_PTR = c_ulong if sizeof(c_void_p) == 4 else c_ulonglong
LPBYTE    = POINTER(c_ubyte)
LPTSTR    = POINTER(c_char)
HANDLE    = c_void_p
PVOID     = c_void_p
LPVOID    = c_void_p

class STARTUPINFO(Structure):
    _fields_ = [("cb",            DWORD),  
                ("lpReserved",    LPTSTR),  
                ("lpDesktop",     LPTSTR),  
                ("lpTitle",       LPTSTR),  
                ("dwX",           DWORD),  
                ("dwY",           DWORD),  
                ("dwXSize",       DWORD),  
                ("dwYSize",       DWORD),  
                ("dwXCountChars", DWORD),  
                ("dwYCountChars", DWORD),  
                ("dwFillAttribute",DWORD),  
                ("dwFlags",       DWORD),  
                ("wShowWindow",   WORD),  
                ("cbReserved2",   WORD),  
                ("lpReserved2",   LPBYTE),  
                ("hStdInput",     HANDLE),  
                ("hStdOutput",    HANDLE),  
                ("hStdError",     HANDLE),]  

class PROCESS_INFORMATION(Structure):
    _fields_ = [("hProcess",    HANDLE),  
                ("hThread",     HANDLE),  
                ("dwProcessId", DWORD),  
                ("dwThreadId",  DWORD),]  


DETACHED_PROCESS = 0x00000008


def main():
	""" the main routine :-)"""  
	usage = "usage: %prog [options] <program path> [<arg 1> <arg n>]"  
	parser = optparse.OptionParser(usage=usage)
	parser.disable_interspersed_args()
	parser.add_option("-c", "--cpuid", default="0", dest="cpuid", help="list of comma separated cpu IDs. E.g. 0,3 or 4,5")  
	parser.add_option("-p", "--priority", default="normal", type="choice", choices=priorities.keys(), dest="priority", help="process priority class. [low, normal, high, realtime] - Default: %default")  
	options, args = parser.parse_args()

	if len(args) < 1: parser.error("incorrect number of arguments")  

	# check cpu IDs
	try:
		cpu_ids = [ int(id) for id in options.cpuid.split(',') ]  
	except:
		parser.error("incorrect cpu id parameter")  

	cpu_count = multiprocessing.cpu_count()
	if not all([ id < cpu_count for id in cpu_ids ]):
		parser.error("invalid cpu id value")  

	# check program path
	if not os.path.exists(args) or not os.path.isfile(args):
		parser.error("incorrect program path")  

	cpu_affinity_mask = 0
	for id in cpu_ids:
		cpu_affinity_mask += (1 << id);

	# re-join the commands to a string
	command = ''  
	for arg in args:

		if ' ' in arg: arg = '"'+arg+'"'  
		if command != '': command += ' '  
		command += arg

	startup_dir = os.path.dirname(args) or None

	priority_class = priorities[options.priority]

	# start the process
	si = STARTUPINFO();
	si.cb = sizeof(si)
	pi = PROCESS_INFORMATION();
	if not windll.kernel32.CreateProcessA(None, command, None, None, False, DETACHED_PROCESS | priority_class, None, startup_dir, byref(si), byref(pi)):
		print("Can't create process.");  
		sys.exit(1)

	# wait some seconds
	time.sleep(check_interval)

	dwProcessMask = DWORD_PTR(0)
	dwSystemMask = DWORD_PTR(0)
	if windll.kernel32.GetProcessAffinityMask ( pi.hProcess,  byref(dwProcessMask), byref(dwSystemMask) ) \
		and (dwSystemMask.value & cpu_affinity_mask):

		validations = 0

		#~ print dwSystemMask.value, dwProcessMask.value, cpu_affinity_mask
		while validations < validation_nb:
			if not windll.kernel32.SetProcessAffinityMask( pi.hProcess, DWORD_PTR(dwSystemMask.value & cpu_affinity_mask) ):
				error_code = windll.kernel32.GetLastError()
				print("Error [%d]: Can't set process affinity mask.", error_code)  
				break

			time.sleep(check_interval)
			if not windll.kernel32.GetProcessAffinityMask ( pi.hProcess, byref(dwProcessMask), byref(dwSystemMask) ):
				print("Error Can't set process affinity mask.")  
				break
			#~ print dwSystemMask.value, dwProcessMask.value, cpu_affinity_mask
			if ( dwSystemMask.value & cpu_affinity_mask ) != dwProcessMask.value:
				validations = 0
			else:
				validations += 1

	else:
		print("Error: Can't set process affinity mask. CPU ID does not exist.")  

	windll.kernel32.CloseHandle(pi.hThread)
	windll.kernel32.CloseHandle(pi.hProcess)

	sys.exit(0)



if __name__ == "__main__":  
	main()