Seltsames Phänomen bei QueryPerformanceCounter und LARGE_INTEGER mit VS2008...



  • Weiß jemand, warum hier ein Unterschied besteht?

    unsigned __int64 RTCTest=0;
    QueryPerformanceCounter((LARGE_INTEGER *)&RTCTest);  //bekommt einen validen Wert
    QueryPerformanceCounter((LARGE_INTEGER *)&pHandle->RTCStartOfScan);  //bleibt auf dem Ursprungswert 0
    

    Dieser Code hat in der Vergangenheit (VS6+VS2005) immer funktioniert, mit dem VS2008 ist es aber nun so, dass die Variable, die Member eines structs ist, keinen Wert mehr zugewiesen bekommt! Sonst gibt es keinen Unterschied, beide sind unsigned __int64. Die Aufrufe waren zwar an verschiedenen Stellen, aber ich habe sie testweise direkt untereinander gepackt und auch andere Member gleichen Typs ausprobiert. Die Werte habe ich beim Breakpoint in der Folgezeile und per OutputDebugString überprüft und anhand eines Datenhaltepunkt, der beweist, dass QueryPerformanceCounter die Variable nicht anrührt.

    Mein Workaround ist jetzt der, dass ich mir den Wert mit einer lokalen Variable hole und per memcpy nach RTCStartOfScan kopiere. Funktioniert wenigstens...

    Ich habe selten etwas so unlogisches erlebt. Wäre klasse, wenn mir das jemand erklären könnte...



  • mehr code? vielleicht ein minimales, lauffähiges beispiel?



  • moar! schrieb:

    mehr code? vielleicht ein minimales, lauffähiges beispiel?

    Habe ich versucht, aber im kleinen Beispielprojekt funktioniert's. Ich poste es trotzdem mal, zum den Ablauf klarer zu machen, denn der ist im Grunde der gleiche (wenn auch aus Wesentliche reduziert). Irgendein Unterschied muss natürlich trotzdem noch vorhanden sein, keine Ahnung...

    #include <windows.h>
    
    typedef struct tag_Handle {
    	unsigned __int64 RTCStartOfScan;
    	unsigned __int64 RTCEndOfScan;
    
    } T_Handle;
    
    void CallQPC(T_Handle *handle) {
    	unsigned __int64 local1;
    	unsigned __int64 local2;
    	QueryPerformanceCounter((LARGE_INTEGER*)&local1);
    	QueryPerformanceCounter((LARGE_INTEGER*)&local2);
    	QueryPerformanceCounter((LARGE_INTEGER*)&handle->RTCStartOfScan);
    	QueryPerformanceCounter((LARGE_INTEGER*)&handle->RTCEndOfScan);
    }
    
    int main() {
    	T_Handle *h;
    	h=(T_Handle*)malloc(sizeof(T_Handle));
    	memset(h,0,sizeof(T_Handle));
    	CallQPC(h);
    }
    


  • Irgendein Unterschied muss natürlich trotzdem noch vorhanden sein, keine Ahnung...

    Wenn du den Unterschied gefunden hast wirst du vermutlich den Fehler gefunden haben. Logisch, hm?



  • hustbaer schrieb:

    Irgendein Unterschied muss natürlich trotzdem noch vorhanden sein, keine Ahnung...

    Wenn du den Unterschied gefunden hast wirst du vermutlich den Fehler gefunden haben. Logisch, hm?

    Tja, das sagt sich so leicht. Das ist ein Riesenprojekt, da könnte ich wahrscheinlich ein Leben lang suchen, ohne fündig zu werden... 😉


  • Mod

    Was sagt der Rückgabewert? Was sagt GetLastError?

    Falsche Speicheradresse? Irgendeine Debug Ausgabe?

    BTW: Warum verwendest Du nicht den im SDK verwendeten Typ LONGLONG? Außerdem hat LARGE_INTEGER auch QuadPart.



  • Martin Richter schrieb:

    BTW: Warum verwendest Du nicht den im SDK verwendeten Typ LONGLONG? Außerdem hat LARGE_INTEGER auch QuadPart.

    Das ist ursprünglich nicht mein Code! Ich habe den übernommen und darf jetzt halt damit leben...

    Der Rückgabewert war erwartungsgemäß FALSE, GetLastError hat "Invalid access to memory location." zurückgegeben, was mich nicht wirklich weitergebracht hat, da das Handle und alle Member problemlos gelesen und geschrieben werden konnten. Zumindest hat mein Wissen und Verständnis nicht ausgereicht.

    Ein Kollege ist aber drauf gekommen. Es lag am Alignment! Da sind ein paar #pragma pack Anweisungen, die das Alignment u.a. für die Handle-Struktur geändert haben. Als ich die struct-Deklaration aus dem push-pop-Block 'rausgenommen hatte, war alles wieder in Ordnung. Der Kollege vermutet, dass sich mit dem VS2008 vielleicht die Implementierung von QueryPerformanceCounter geändert hat (SSE-Kram o.ä.) und deshalb plötzlich der vorher funktionierende Code Probleme gemacht hat...



  • Siehe auch:

    "Why does QueryPerformanceFrequency fail with error 998?" http://bobmoore.mvps.org/Win32/w32tip75.htm

    Martin



  • Mmacher schrieb:

    Siehe auch:

    "Why does QueryPerformanceFrequency fail with error 998?" http://bobmoore.mvps.org/Win32/w32tip75.htm

    Martin

    Interessanter Link! Hätte ich den mal früher gekannt. Während der Typ ca. 1 Stunde gebraucht hat war es bei mir eher ein halber Tag... mit Hilfe...



  • Hallo.

    Nicht jeder Prozessor (Intel/AMD/Via usw.) hat den Counter. Bevor QueryPerformanceIrgendwas aufgerufen wird immer erst checken, ob der Prozessor das überhaupt kann.

    Gruß

    Lars


Anmelden zum Antworten