Latente Defekte zutage fördern

Multi-Core-Verarbeitung deckt auf

Latente Defekte
zutage fördern

Bestehende softwarebasierte Systeme bedürfen gelegentlich der Modernisierung. Aus Gründen der Kosteneffektivität bietet es sich bei dieser Gelegenheit häufig an, eine Migration auf einen Multi-Core-Prozessor vorzunehmen, denn verglichen mit Prozessoren, die nur über einen Kern verfügen, bergen Multi-Core-Prozessoren das Potenzial einer deutlichen Performance-Steigerung.
Um das gebotene Performance-Potenzial jedoch wirklich ausschöpfen zu können, muss der Code für den nebenläufigen Betrieb geschrieben sein. Den bestehenden Code entsprechend umzuschreiben, ist jedoch eine durchaus riskante Sache, denn bekanntermaßen besteht bei jeder Änderung an einer Software die Gefahr, dass sich neue Defekte einschleichen. Hinzu kommen die mit der Nebenläufigkeit zusammenhängenden Defekte wie etwa Data Races, Deadlocks und Starvation. Diese kommen nur allzu leicht vor, sind dafür aber extrem schwierig zu finden. Wenn der ursprüngliche Code auf einer Single-Thread-Struktur basierte, versteht es sich von selbst, dass bei der Migration größte Vorsicht angewendet werden muss. Weniger offensichtlich ist dagegen die Tatsache, dass auch ein Code, der bereits in mehrere Threads gegliedert ist und vielleicht schon jahrelang ohne Probleme auf einem Single-Core-Prozessor gelaufen ist, ein hohes Fehlerrisiko birgt, wenn er auf einmal von einem Multi-Core-Prozessor verarbeitet wird. Um die Gründe hierfür zu erläutern, muss auf die subtilsten Bugs eingegangen werden, die in nebenläufigen Systemen auftreten können. Gemeint sind die so genannten Data Races.

Data Races

Es handelt sich dabei um Race Conditions, die bei Zugriffen auf einen gemeinsam genutzten Speicher auftreten können. Zu einem Data Race kommt es, wenn mehrere Verarbeitungs-Threads auf eine gemeinsam genutzte Speicherstelle zugreifen, wenn mindestens einer dieser Threads an diese Speicherstelle schreibt und wenn die Zugriffe nicht durch eine explizite Synchronisation (z.B. durch Freigabe eines Mutex oder Setzen eines Semaphoren) separiert werden. Das Einkreisen und Diagnostizieren von Data Races gestaltet sich recht schwierig, denn die Speicherinhalte werden durch die Data Races nicht unbedingt verfälscht. Kommt es zu einer Verfälschung des Speicherinhalts, muss dies außerdem nicht in jedem Fall einen von außen erkennbaren Bug auslösen. Ob Data Races einen Ausfall zur Folge haben, hängt in hohem Maße vom Timing des jeweiligen Verarbeitungsdurchgangs ab. Ein bestimmter Testfall kann hunderte Male bei exakt gleichen Eingangsbedingungen erfolgreich ablaufen, um dann aus unerfindlichen Gründen fehlzuschlagen, weil eine Race Condition eine unerwünschte Reaktion ausgelöst hat. Tritt ein Funktionsfehler auf, ist er schwierig zu diagnostizieren, da die genaue Abfolge der Speicherzugriffe, die die Störung hervorgerufen hat, nur schwierig zu reproduzieren ist.

Verzahnung von Speicherzugriffen

Was Data Races so problematisch macht, ist die Tatsache, dass die Art und Weise, auf die die Speicherzugriffe der verschiedenen Threads ineinandergreifen, das heißt miteinander verzahnt sind, weitgehend nicht-deterministisch erfolgt. Selbst bei Programmen von recht überschaubarem Umfang ist die Zahl möglicher Verzahnungen enorm hoch, sodass es unmöglich ist, alle denkbaren Kombinationen zu überprüfen.

Seiten: 1 2 3Auf einer Seite lesen

GrammaTech Inc.
www.grammatech.com

Das könnte Sie auch Interessieren