Grid schneller Laden?

01/21/2013 11:36 Trollface-#1
Hi,

hab derzeit nen kleines Problem (Naja, eher stört mich das),
undzwar lade ich ungefähr 500 Files (Zonen) im Spiel, wo angegeben wird ob die Koordinaten X,Y betretbar bzw. unbetretbar sind.

Alles kein Problem, allerdings braucht der schon etwas lange, um die ganzen Zones zu laden, und somit wollte ich fragen wie man den Prozess verschnellern kann.

Code:
	struct MapZones
	{
		short x;
		short y;
		std::vector<std::vector<char>> grid;
	}; MapZones MapZones;

	bool ReadFileZone(std::string filepath)
	{
		//Read File, Error Handling
		//Erste 2 Bytes für x, y auslesen


		MapZones.grid.resize(MapZones.y);

		for(auto i = 0; i < MapZones.y; ++i)
		{
			for(auto a; a < MapZones.x; ++a)
			{
				MapZones.grid[i].push_back(std::getc(file));
			}
		}
	}
Über Hilfe währe ich dankbar. :)
01/21/2013 22:38 Nightblizard#2
Wenn du mit Windows arbeitest kannst du die ppl nutzen.

[Only registered and activated users can see links. Click Here To Register...]
01/21/2013 23:38 MrSm!th#3
std::for_each nutzt doch afaik Loop-Unwinding, um die Traversierung von Standard-Containern zu beschleunigen.

Die Zeile
Quote:
MapZones.grid.resize(MapZones.y);
lässt sich natürlich auch auf die innere Schleife für die X-Achse übertragen.

Plattformunabhängiger als mit Windows Parallels ginge es sicherlich auch mit std::async() bzw. std::thread im Allgemeinen.

Sinnvoll wäre es sicherlich auch, den Inhalt der Datei in Größeren Blöcken als 1 Byte pro Schleifendurchlauf auszulesen.
01/22/2013 19:30 Trollface-#4
Quote:
Originally Posted by Nightblizard View Post
Wenn du mit Windows arbeitest kannst du die ppl nutzen.

[Only registered and activated users can see links. Click Here To Register...]
Läuft, danke. ;)

Quote:
Originally Posted by MrSm!th View Post
std::for_each nutzt doch afaik Loop-Unwinding, um die Traversierung von Standard-Containern zu beschleunigen.

Die Zeile
lässt sich natürlich auch auf die innere Schleife für die X-Achse übertragen.

Plattformunabhängiger als mit Windows Parallels ginge es sicherlich auch mit std::async() bzw. std::thread im Allgemeinen.

Sinnvoll wäre es sicherlich auch, den Inhalt der Datei in Größeren Blöcken als 1 Byte pro Schleifendurchlauf auszulesen.
Danke.
Den Inhalt habe ich auch schon versucht mit größeren Blöcken auszulesen, die Performance ist aber nur minimal gestiegen, aber das hat sich ja jetzt sowieso erledigt.

Allerdings habe ich nun nen anderes Problem mit der Thread safety, undzwar:

Code:
class TMap
{
	private:
		struct Map
		{
			int vnum;
			MapZones zones;
			std::vector<TSocket> players;
			std::vector<Portals> portals;
			std::vector<Entitys> entitys;
		};

		std::vector<Map> map; //Size 500+
	public:
		Map Map();
		Map ~Map();

		bool AddPlayerToMap(TSocket *Client);
		bool RemovePlayerFromMap(TSocket *Client);
		std::vector<Map> *GetMapList(std::vector<Map> v);
};
Angenommen es laufen 1000~ Socket Threads, jeder Thread muss dauernd auf den Map Vector zugreifen (zum lesen) um z.B. alle Spieler auf allen Maps zu bekommen, nur habe ich keine Idee wie ich das Performance mäßig schnell & sicher hinbekomme.
Habe eventuell überlegt den Vector in die Public zu klatschen und als atomic (C++11 Standart) zu deklarieren, so das getrost alle Threads mit dem Vector arbeiten können, allerdings sagt mir mein Gefühl das ich auf dem falschen Wege bin, hoffe mir kann da jemand weiterhelfen wie das zu lösen ist.

Nachtrag: Hab vergessen zu erwähnen, das wenn nun ein Thread den Vector zum lesen anfordert, und er ihn in einer Schleife durchläuft und genau in diesem Moment ein Spieler z.B. entfernt wird von der Map, fliegt mir das Ding um die Ohren. (ist selbstverständlich)
01/22/2013 20:33 MrSm!th#5
Quote:
Angenommen es laufen 1000~ Socket Threads
Man sollte für Sockets eigentlich select nutzen und nicht für jede Verbindung einen Thread haben.

Quote:
Habe eventuell überlegt den Vector in die Public zu klatschen und als atomic (C++11 Standart) zu deklarieren, so das getrost alle Threads mit dem Vector arbeiten können, allerdings sagt mir mein Gefühl das ich auf dem falschen Wege bin, hoffe mir kann da jemand weiterhelfen wie das zu lösen ist.
Ein vector kann nicht atomar sein oO

std::mutex und std::lock sind was du suchst.
01/22/2013 21:07 Trollface-#6
Quote:
Originally Posted by MrSm!th View Post
Man sollte für Sockets eigentlich select nutzen und nicht für jede Verbindung einen Thread haben.

Ein vector kann nicht atomar sein oO

std::mutex und std::lock sind was du suchst.
Stimmt, dann bleibt die std::atomic variante wohl weg.
Dann werde ich nun auf std::mutex greifen, danke.

Bezüglich der select Funktion, konnte ich mich nicht entscheiden und habe dann die Thread variante gewählt.
Hoffe es ist nicht so "schlimm", hab zwar gelesen das die select Funktion bei vielen Client's besser währe aufgrund des Speichers, aber würde ich gerne erstmal so lassen.

Ansonsten kann hier zu,
bedanke mich nochmals an euch beiden. :)
01/22/2013 21:59 MrSm!th#7
1000 Threads...merkste selbst, ne? ;<