سؤال

لدي بعض التعليمات البرمجية لتحويل قيمة الوقت التي تم إرجاعها من QueryPerformancoCoTer إلى قيمة مزدوجة في المليفي الثانوي، لأن هذا هو أكثر ملاءمة لحساب مع.

الوظيفة تبدو وكأنها هذه:

double timeGetExactTime() {
    LARGE_INTEGER timerPerformanceCounter, timerPerformanceFrequency;
    QueryPerformanceCounter(&timerPerformanceCounter);
    if (QueryPerformanceFrequency(&timerPerformanceFrequency)) {
        return (double)timerPerformanceCounter.QuadPart / (((double)timerPerformanceFrequency.QuadPart) / 1000.0);
    }
    return 0.0;
}

المشكلة التي أواجهها مؤخرا (لا أعتقد أن لدي هذه المشكلة من قبل، ولم يتم إجراء أي تغييرات على التعليمات البرمجية) هي أن النتيجة ليست دقيقة للغاية. النتيجة لا تحتوي على أي عشري، لكنها أقل دقة من 1 مللي ثانية.

عندما أدخل التعبير في المصحح، فإن النتيجة دقيقة كما أتوقع.

أنا أفهم أن مزدوج لا يمكن أن يحمل دقة عدد صحيح 64 بت، ولكن في هذا الوقت، يلزم PeristeranceCeCounter فقط 46 بت (ويجب أن يكون مزدوج قادرا على تخزين 52 بت دون خسارة) علاوة على ذلك يبدو من الغريب أن يستخدم المصحح تنسيق مختلف للقيام بالانقسام.

فيما يلي بعض النتائج التي حصلت عليها. تم تجميع البرنامج في وضع تصحيح الأخطاء، تم تعيين وضع النقطة العائمة في خيارات C ++ إلى الافتراضي (دقيق (/ FP: دقيق))

timerPerformanceCounter.QuadPart: 30270310439445
timerPerformanceFrequency.QuadPart: 14318180
double perfCounter = (double)timerPerformanceCounter.QuadPart;
30270310439445.000

double perfFrequency = (((double)timerPerformanceFrequency.QuadPart) / 1000.0);
14318.179687500000

double result = perfCounter / perfFrequency;
2114117248.0000000

return (double)timerPerformanceCounter.QuadPart / (((double)timerPerformanceFrequency.QuadPart) / 1000.0);
2114117248.0000000

Result with same expression in debugger:
2114117188.0396111

Result of perfTimerCount / perfTimerFreq in debugger:
2114117234.1810646

Result of 30270310439445 / 14318180 in calculator:
2114117188.0396111796331656677036

هل يعرف أحد لماذا تكون الدقة مختلفة في مراقبة مصحح الأخطاء مقارنة بالنتيجة في برنامجي؟

تحديث: حاولت خصم 30270310439445 من timerperformancecounter.quadpart قبل القيام بالتحويل والقسمة، ويبدو أنه دقيق في جميع الحالات الآن. ربما السبب الذي يجعلني أراه فقط أن هذا السلوك قد يكون الآن لأن وقت تشغيل جهاز الكمبيوتر الخاص بي هو الآن 16 يوما، وبالتالي فإن القيمة أكبر مما كنت معتادا عليه؟ لذلك يبدو أنه مشكلة دقة الانقسام بأعداد كبيرة، لكن لا يزال لا يفسر سبب عدم صحة القسم في نافذة الساعة. هل يستخدم نوع أعلى الدقة من ضعف النتائج؟

هل كانت مفيدة؟

المحلول 2

شكرا، باستخدام عشري ربما يكون حلا أيضا. في الوقت الحالي، اتخذت نهجا مختلفا قليلا، والذي يعمل أيضا جيدا، على الأقل طالما أن برنامجي لا يعمل لفترة أطول من أسبوع أو نحو ذلك دون إعادة التشغيل. أتذكر فقط عداد الأداء من وقت بدء تشغيل البرنامج، وطرح هذا من العداد الحالي قبل التحويل إلى المزدوج والقيام بالتقسيم.

لست متأكدا من الحل الذي سيكون أسرع، أعتقد أنني يجب أن نظرا للقياس أولا.

bool perfTimerInitialized = false;
double timerPerformanceFrequencyDbl;
LARGE_INTEGER timerPerformanceFrequency;
LARGE_INTEGER timerPerformanceCounterStart;
double timeGetExactTime()
{
    if (!perfTimerInitialized) {
        QueryPerformanceFrequency(&timerPerformanceFrequency);
        timerPerformanceFrequencyDbl = ((double)timerPerformanceFrequency.QuadPart) / 1000.0;
        QueryPerformanceCounter(&timerPerformanceCounterStart);
        perfTimerInitialized = true;
    }

    LARGE_INTEGER timerPerformanceCounter;
    if (QueryPerformanceCounter(&timerPerformanceCounter)) {
        timerPerformanceCounter.QuadPart -= timerPerformanceCounterStart.QuadPart;
        return ((double)timerPerformanceCounter.QuadPart) / timerPerformanceFrequencyDbl;
    }

    return (double)timeGetTime();
}

نصائح أخرى

Adion،

إذا كنت لا تمانع في ضرب الأداء، ألقي بأرقام quadpart الخاص بك إلى عشري بدلا من المزدوج قبل تنفيذ التقسيم. ثم يلقي الرقم الناتج مرة أخرى لمضاعفة.

أنت تصحيح بحجم الأرقام. إنه يرمي دقة حسابات النقطة العائمة.

لمزيد من هذا الأمر أكثر مما أرادت أن تعرفه، انظر:

ما يجب أن يعرفه كل عالم الكمبيوتر عن الحساب العائمhttp://docs.sun.com/source/806-3568/ncg_goldberg.html.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top