איך משווים נכון מהירות בין גרסאות תוכנה ב-Windows

· עודכן בתאריך: · · Windows, Benchmark, Performance, Profiling, Power Management

רוצים להשוות בין גרסה A לגרסה B של תוכנה ב-Windows. מה שהכי אסור לעשות אז הוא להריץ פעם אחת בכל גרסה על אותו מחשב ולומר “נראה ש-B מהיר ב-8%”.

ייתכן שה-8% האלה הם באמת הבדל קוד. אבל בפועל, הסיפור הנפוץ ב-benchmark ל-Windows הוא שמצב חשמל,‏ power plan, חום, עדכונים ברקע, אינדקס חיפוש, סריקת אנטי-וירוס,‏ affinity, סדר ההרצה, מצב מטמון — אחד מאלה הוא הגורם. זו עבודה שקטה של סתימת תנאים אחד אחד.

הזהות האמיתית מאחורי "נראה שמהיר ב-8%"תרשים המראה שהבדל שיוצא מהרצה בודדת בכל גרסה עשוי להיות הבדל קוד, אבל בפועל בדרך כלל זה חשמל, חום, רעש או מטמון, ונדרשת עבודה של סתימת תנאים אחד אחד.ייתכןהזהות הנפוצההרצה בודדת בכל גרסה, השוואהמתקבל 'נראה שמהיר ב-8%'הבדל קוד אמיתיחשמל · חום · רעש · מטמוןסתימת התנאים אחד אחד

איור 1: הבדל מהרצה בודדת לא בהכרח הבדל קוד — אי אפשר לקבוע עד שלא סותמים את התנאים.

במאמר הזה נסכם דרך להשוות מהירות הרצה בין גרסאות שונות של תוכנה ב-Windows, כמה שיותר קרוב להבדל הקוד עצמו. היעד הוא בעיקר Windows 11, אבל רוב powercfg ו-start וכדומה עובדים באותה צורה גם ב-Windows 10.

מונחים שכדאי לקבוע מראש

בגוף המאמר יופיעו מונחים באנגלית. כדי לא להיתקע בהופעה הראשונה, נרכז אותם קודם.

מונח משמעות
ETW ‏Event Tracing for Windows. תשתית מעקב שמוכללת ב-Windows. אפשר לרשום יחד אירועים שמערכת ההפעלה, דרייברים ויישומים מוציאים
WPR /‏ WPA ‏Windows Performance Recorder ו-Windows Performance Analyzer. כלי לרישום עקבות ETW וכלי לפתוח ולנתח אותן, ושניהם כלולים ב-Windows ADK
clean boot הליך שמכבה שירותים ואפליקציות הפעלה שאינם של Microsoft, ומפעיל בהרכב מינימלי. משמש לצמצום רעש מאפליקציות קבועות
PGO ‏Profile-Guided Optimization. מנגנון שמשתמש בסטטיסטיקת הסתעפויות וקריאות שנאספה בהרצה אחת, להחלטת אופטימיזציה ב-build הבא. תנאי ה-build משתנים, ולכן זה סעיף לבדיקה אם היעדים להשוואה תואמים
p95 /‏ p99 אחוזון. כשמסדרים את כל ה-run-ים מהמהיר ביותר, הערך שנמצא במיקום ה-95% /‏ 99% מלמטה. “פעם אחת מכל 20 זה איטי יותר מזה” זה p95
NUMA ‏Non-Uniform Memory Access. הרכב שבו המרחק מה-CPU לזיכרון לא אחיד. מהירות הגישה לזיכרון משתנה לפי הצומת שבו מתבצעת ההרצה
חניית ליבות (core parking) מנגנון ניהול חשמל שמרדים מעבדים לוגיים שלא בשימוש, כשהעומס נמוך

קודם המסקנה

אם מחלצים את מה שמשפר שחזוריות, זה שש הנקודות הבאות.

  1. קובעים קודם “מה רוצים להשוות” האם רוצים לראות הבדל קוד, או חוויית משתמש אמיתית — הסביבה שצריך לתאם משתנה בהתאם.

  2. מתעדים power mode ו-power plan כשני דברים נפרדים ב-Windows, אם מתעלמים כאן ברשלנות, ההשוואה נוטה להפוך להשוואת מדיניות חיסכון בחשמל של מערכת ההפעלה.

  3. מפרידים בין ההרצה הראשונה הקרה לבין המצב היציב אחרי שהתחמם מהיר רק בפעם הראשונה, או איטי רק בהמשך — זה לא נדיר.

  4. מריצים לסירוגין כמו A→B→A→B אם מריצים קודם את כל A ורק אחר כך את B, נספגת הטיה של חום ומצב פעילות ברקע.

  5. מסתכלים לא רק על הממוצע, אלא גם על החציון ועל הפיזור ערך חריג בודד יכול לשבור את התמונה הכוללת. הממוצע שביר יותר ממה שנראה.

  6. אם ההבדל קטן, חופרים עד הסיבה עם ETW /‏ WPR אם דנים רק לפי תחושה, שני הצדדים נשארים בלי גיבוי, ומגיעים לקווים מקבילים.

מפת הידע של המאמר

המאמר הזה עוסק ביכולת השחזור בהשוואת מהירות בין גרסאות של תוכנית ב-Windows, ומראה שקיבוע ותיעוד של שתי שכבות הגדרת חשמל — Power mode (overlay) ו-Power plan — הם תנאי בסיס. הבדל ב-Power mode משפיע על התנהגות ה-PPM כמו core parking, ובמכשירים התומכים ב-Modern Standby אפשרויות ה-Power plan עצמן מוגבלות לרוב למשפחת Balanced. תהליכי רקע כמו אינדוקס חיפוש, סריקות Defender והתראות עלולים לגרום לפיזור בערכי המדידה, וניתן להקטין זאת עם הגדרות החרגה, אתחול נקי (clean boot), והשתקת התראות. מומלץ למדוד בנפרד Wall-clock time,‏ CPU time ו-Cycle count באמצעות QueryPerformanceCounter,‏ GetProcessTimes ו-QueryProcessCycleTime בהתאמה, וכאשר ההבדל קטן והסיבה אינה ברורה — לתעד עקבות ETW עם WPR ולהשוות אותם עם WPA.

מפת הידע של יכולת השחזור בהשוואת benchmark בין גרסאות ב-Windowsתרשים המראה שקיבוע ותיעוד של שתי שכבות הגדרת חשמל, Power mode ו-Power plan, הם תנאי ליכולת שחזור של benchmark, שתהליכי רקע כמו אינדוקס חיפוש וסריקות Defender גורמים לפיזור בערכי המדידה וניתן להקטין זאת עם הגדרות החרגה או אתחול נקי, שמדידת Wall-clock time,‏ CPU time ו-Cycle count נעשית כל אחת עם API ייעודי, ואת תהליך ההעמקה עם WPR ו-WPA כשהפער קטן.מחייבמחייבמוגדר באמצעותאינו מתיישב עםמוגדר באמצעותעלול לגרום למצמצםמצמצםמצמצםמשתמש במשתמש במחייבמענה מומלץ לנבדק באמצעותנבדק באמצעותנבדק באמצעותמוגדר באמצעותמוגדר באמצעותמחייבמשתמש במשתמש במשתמש באינו מתיישב עםעלול לגרום למשתמש בשחזוריות של מדידת ביצועיםמצב חשמל / תוכנית חשמל (PPM)‏Power plan (תוכנית חשמל)powercfgהתקנים התומכים ב-Modern StandbyCore Parkingבניית אינדקס החיפושפיזור התוצאות במדידת ביצועיםהגדרת החרגה (החרגת תיקייה)אתחול נקי (clean boot)‏Do not disturb (השתקת התראות)Windows Performance Recorder(WPR)ETW(Event Tracing for Windows)Windows Performance Analyzer(WPA)תוצאת מדידה עם פער קטן או בלתי מוסבר‏Wall-clock time (זמן אמיתי)QueryPerformanceCounter(QPC)‏CPU time (זמן משתמש + זמן ליבה)GetProcessTimes‏Cycle count (מספר מחזורי מעבד)QueryProcessCycleTimeמחלקת עדיפות (priority class)הפקודה startזיקת מעבד (affinity mask)קבוצות מעבדים (Processor Groups)

בתרשים, קו מלא מציין קשר שמתקיים תמיד וקו מקווקו מציין קשר מותנה (תנאי ההתקיימות מפורטים בהסבר של כל קשר בעמוד המפורט). רשימת כל הקשרים (סך הכול 25, עם אסמכתה ורמת ודאות) והגדרות המושגים המרכזיים מרוכזות בעמוד המפורט של מפת הידע (ביפנית). נתונים: JSON-LD / Turtle

קודם קובעים מה רוצים להשוות

“השוואת מהירות” נשמעת כמושג אחד, אבל בפועל יש שני סוגים.

1. השוואה שרוצים לראות בה הבדל קוד

השוואה שרוצה לדעת אם המימוש עצמו נהיה מהיר יותר, בעקבות שינוי אלגוריתם, שינוי מבנה נתונים, אופטימיזציית מהדר, או עדכון זמן ריצה.

במקרה הזה, מצמצמים ככל האפשר את רעש הסביבה. פגישת benchmark ייעודית, קיבוע power mode, עצירת התראות, דיכוי אינדקס חיפוש וסנכרון, ואם צריך — גם clean boot.

2. השוואה שרוצים לראות בה חוויית משתמש אמיתית

השוואה שרוצה לדעת את המהירות שהמשתמש חש בפועל ב-Windows הרגיל שלו אחרי ההפצה.

במקרה הזה, אסור לבטל את כל הרעש שקיים במציאות. השוואה בסביבה יומיומית ריאלית שכוללת סנכרון OneDrive,‏ Defender, התראות, והגדרות חשמל רגילות, מתקרבת יותר לתוצאה מציאותית.

אם מערבבים בין שני אלה, המסקנה מתפתלת. דברים כמו “בלאב זה 12% מהיר יותר, אבל במציאות זה סטיית תקן” או “במציאות זה מהיר יותר, אבל בזמן CPU אין שינוי” קורים בקלות.

לא מערבבים בין שני סוגי ההשוואהתרשים המראה שבהשוואה שרוצים בה הבדל קוד מצמצמים ככל האפשר רעש סביבה, ובהשוואה שרוצים בה חוויית משתמש אמיתית משאירים רעש מציאותי בסביבה יומיומית, ושעירוב בין השניים מפתל את המסקנה.הבדל קודחוויית משתמש אמיתיתאם מערבביםמה רוצים להשוותסביבת מעבדה בלי רעשסביבה יומיומית עם רעשהמסקנה מתפתלת

איור 2: הסביבה שצריך לתאם הפוכה לפי המטרה, ולכן קובעים קודם באיזה סוג השוואה מדובר.

הגורם העיקרי לתנודתיות ב-Windows

תחילה נרכז בגסות מה גורם לתנודתיות בתוצאות.

שכבה גורם תנודתיות דוגמה טיפוסית
חומרה CPU /‏ GPU, זיכרון,‏ SSD, קירור דקות המחשב הנייד, קיום מעמד קירור
קושחה BIOS /‏ UEFI, בקרת יצרן מדיניות חיסכון בחשמל, בקרת מאוורר
מערכת הפעלה build של Windows, דרייברים, מצב עדכון גם באותו מחשב, ההתנהגות משתנה אחרי עדכון
חשמל AC /‏ DC,‏ power mode,‏ power plan הזנה מסוללה זה עולם אחר
חום טמפרטורת חדר, מאוורר, עומס קודם Turbo רק בפעם הראשונה, איבוד קצב בהמשך
רקע Update,‏ Defender, סנכרון, התראות סריקה או סנכרון רצים תוך כדי ההרצה
תזמון עדיפות,‏ affinity,‏ NUMA הקצאת ה-CPU משתנה לפי המחשב
נתונים / מטמון מטמון מערכת ההפעלה, מטמון יישום איטי רק בפעם הראשונה, מהיר רק מהפעם השנייה ואילך
תנאי build Debug /‏ Release,‏ PGO, קיום לוגים בפועל משווים דברים שונים לגמרי

בקיצור, גם “אותו מחשב Windows” הוא ניסוי אחר אם התנאים לא מתואמים.

בלי תנאים מתואמים זה ניסוי אחרתרשים המראה שגם כשמודדים על אותו מחשב Windows, אם תנאים רב-שכבתיים מחומרה ועד חשמל, חום, רקע ותנאי build לא מתואמים, זה בפועל ניסוי אחר, ורק תיאום התנאים הופך את זה להשוואה.התנאים לא מתואמיםתיאום ותיעוד תנאים רב-שכבתייםמדידה על אותו מחשב Windowsבפועל, ניסוי אחררק אז זו השוואה

איור 3: גם כשהמחשב זהה, אם התנאים בין השכבות לא מתואמים, זה לא נחשב השוואה.

מפרידים בין power mode ל-power plan

זו נקודה חשובה מאוד.

ב-Windows קיימים ה-Power mode של אפליקציית ההגדרות, וה-Power plan המסורתי (תוכנית החשמל שרואים ב-powercfg). המראה דומה ולכן נוטים לערבב, אבל טיפול רשלני הופך את ההשוואה לבלגן.

באפליקציית ההגדרות של Windows, אפשר לבחור את ה-Power mode דרך Settings > System > Power & battery. לפי התיעוד של Microsoft, אפשר להחליף בין Best power efficiency,‏ Balanced,‏ Best performance לכל אחד מ-Plugged in /‏ On Battery. בנוסף, כש-Power mode משתנה, זה משפיע גם על ההגדרות הקשורות לחשמל שמאחוריו ועל התנהגות ה-PPM‏ (‏Processor Power Management). כלומר, גם רק הבדל כאן עלול לשנות את מדיניות חניית הליבות והקנה מידה של הביצועים.

מצד שני, Power plan הוא תוכנית חשמל מסורתית כמו Balanced,‏ High performance. אפשר לבדוק עם powercfg /list או powercfg /getactivescheme.

מה שמסבך כאן הוא שב-Windows קיימים גם שכבת-על (overlay) של power mode וגם power plan. אם מציגים את הקשר בציור, זה נראה כך:

שתי השכבות של power mode ו-power planתרשים המראה שאפליקציית ההגדרות שולטת בשכבת-העל של Power mode ו-powercfg שולט בתוכנית החשמל, ששתי השכבות יחד עם ההזנה מ-AC או סוללה קובעות את הגדרת החשמל שבאמת פועלת, שמשפיעה על תקרת התדר, חניית ליבות וקנה מידה של ביצועים.השכבה התחתונה: Power plan - תוכנית חשמלBalancedHigh performancecustom planהשכבה העליונה: Power mode - שכבת-עלBest power efficiencyBalancedBest performanceאפליקציית ההגדרות — Power mode תחת Power and batteryמעבר עם powercfg /setactiveההגדרה שבאמת פועלת — PPM ותת-הקבוצה הגרפיתהזנה מ-AC או מסוללהתקרת התדר / חניית ליבות / קנה מידה של ביצועים

איור 4: שתי השכבות — Power mode (שכבת-על) ו-Power plan — יחד עם AC/DC קובעות את הגדרת החשמל שבאמת פועלת.

לא ניתן לקבוע את ההתנהגות בפועל רק מהשכבה העליונה או רק מהתחתונה. לכן, בתוצאת benchmark, לפחות תעדו:

  • האם AC או סוללה
  • מהו ה-Power mode
  • מהו ה-Active power plan

תוצאת benchmark שלא רשומים בה שלושת אלה, אי אפשר לשחזר את התנאים כשחוזרים אליה מאוחר יותר.

שלושת הפרטים שתמיד מתעדיםתרשים המראה שאם לא מתעדים יחד עם התוצאה האם זה AC או סוללה, מהו ה-Power mode ומהו ה-Active power plan, לא ניתן לשחזר את התנאים בבדיקה מאוחרת יותר.AC או סוללהמתועד יחד עם התוצאהPower modeActive power planהתנאים ניתנים לשחזור בהמשך

איור 5: שלושת הפרטים סביב החשמל הם המינימום שבלעדיו התוצאה בלתי ניתנת לשחזור.

קודם מקבעים תנאי חשמל

  1. מחשב נייד תמיד משווים בהזנת AC הפעלה מסוללה נוטה להחיל הגבלה בלתי מכוונת.

  2. מקבעים את ה-Power mode לצורך benchmark, מנסים קודם Best performance.

  3. מתעדים את ה-Active power plan שומרים עם powercfg את הערך הנוכחי.

powercfg /list
powercfg /getactivescheme

הפלט של powercfg /list מוצג בתיעוד של Microsoft בצורה הבאה. לתוכנית הפעילה מתווסף * בסוף השורה. בסביבה עברית, הכותרת ושם התוכנית יוצגו בשפה המקומית.

Existing Power Schemes (* Active)
-----------------------------------
Power Scheme GUID: {guidPlan1}  (Balanced) *
Power Scheme GUID: {guidPlan2}  (Power saver)

את ה-GUID שהתקבל כאן, מעתיקים ישירות לעמודת power_plan בקובץ התוצאה. הנקודה החשובה היא לתעד GUID ולא שם. גם כש”מאוזן” נראה זהה, ייתכן שזו תוכנית אחרת ששוכפלה או הותאמה אישית.

  1. אם צריך, מחליפים ל-High performance
# Balanced
powercfg /setactive 381b4222-f694-41f0-9685-ff5bb260df2e

# High performance
powercfg /setactive 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c

האם אפשר להחליף Power mode עם פקודה

זו נקודה שקל להיתקע בה. ברשימת אפשרויות שורת הפקודה הפרסומית של powercfg, אין אפשרות לבחור מחדש את Power mode (שכבת-העל) עצמו. ההליך הרשמי להחלפה הוא דרך Settings > System > Power & battery באפליקציית ההגדרות.

מצד שני, powercfg תומך בקריאה וכתיבה של ערכי ההגדרה של סכימת שכבת-העל. בתיעוד כתובים הדברים הבאים:

  • אם מעבירים ל-powercfg /q את הכינוי (alias) ותת-הקבוצה של שכבת-העל, אפשר לקרוא את ההגדרה שבצד שכבת-העל
  • powercfg /setacvalueindex ו-/setdcvalueindex ניתנים לשימוש גם בסכימת שכבת-העל
  • אם לא מציינים סכימה, היעד הוא שכבת-העל הפעילה כרגע (ואם אין שכבת-על, תוכנית החשמל הנוכחית)
  • אפשר לבדוק את רשימת הכינויים עם powercfg /aliases

כלומר, מה שאפשר לעשות בפקודה הוא “לקרוא ולכוונן את תוכן שכבת-העל הפעילה כרגע”, ולא “לשנות איזו שכבת-על נבחרת”. כנוהל שחזורי ל-benchmark, מעשי יותר לקבע את Power mode ידנית באפליקציית ההגדרות, ולכתוב את הערך בתוצאה. במסמך הנוהל רושמים במפורש “הוגדר Power mode = Best performance”, ובודקים על המסך בכל הרצה.

מה powercfg יכול ומה לאתרשים המראה ש-powercfg יכול לקרוא ולכוונן את תוכן שכבת-העל הפעילה, אבל אין אפשרות לשנות איזו שכבת-על נבחרת, ולכן מעשי לקבע את Power mode ידנית באפליקציית ההגדרות ולתעד את הערך.יכוללא יכולpowercfgקריאה וכוונון של תוכן שכבת-העלשינוי איזו שכבת-על נבחרתקיבוע ידני באפליקציית ההגדרות ותיעוד

איור 6: לא ניתן לשנות בפקודה את בחירת שכבת-העל, ולכן מקבעים ידנית ומתעדים.

“High performance לא מופיע” זה מצב רגיל

גם זו נקודת היתקעות. לפי התיעוד של Microsoft, במכשירים שתומכים ב-Modern Standby, מותרות רק Balanced או תוכניות שנגזרות מ-Balanced. לכן, לא “High performance לא נמצא, זה תקול?”, אלא ייתכן שזה תכנון המכשיר, ככה זה.

בנוסף, Microsoft מנחה ש”אם Power mode לא ניתן לשינוי, ייתכן שנבחרה custom power plan, ולכן כדאי לנסות קודם לבחור Balanced”. כשה-UI של Power mode לא זז, כדאי לחשוד כאן ראשון.

איך רואים את המקרה שבו High performance לא מופיעתרשים המראה שבמכשירים שתומכים ב-Modern Standby, רק Balanced או תוכניות שנגזרות ממנו מותרות, ולכן היעדר High performance הוא תכנון, וכש-UI של Power mode לא זז, חושדים ראשון שנבחרה custom plan ומנסים Balanced קודם.High performance לא נמצאאם תומך ב-Modern Standby, זה תכנוןה-UI של Power mode לא זזחושדים באפשרות custom planמנסים לבחור קודם Balanced

איור 7: היעדר תוכנית או UI שלא זז לא בהכרח תקלה — קודם בודקים את תכנון הדגם ואת בחירת התוכנית.

סותמים רעש רקע

Windows, גם כשרוצים למדוד בשקט, מריץ ברקע עדכון, בניית אינדקס וסריקה. תחילה נצמצם את הכמות הזו.

קודם מפעילים מחדש וממתינים שיירגע

אחרי שינוי הגדרה, מפעילים מחדש פעם אחת, לא מריצים מיד אחרי הכניסה, וממתינים כמה דקות. מיד אחרי ההפעלה, עדכון, אינדקס, סנכרון,‏ Defender ותהליכים קבועים שונים עדיין פעילים.

מפעילים מחדש וממתינים שיירגעתרשים המראה שאחרי שינוי הגדרה מפעילים מחדש פעם אחת, ומכיוון שמיד אחרי ההפעלה עדכון, אינדקס, סנכרון ו-Defender עדיין פעילים, לא מריצים מיד אחרי הכניסה אלא ממתינים כמה דקות לפני שמתחילים למדוד.שינוי הגדרההפעלה מחדש פעם אחתהמתנה של כמה דקות אחרי הכניסהורק אז מתחילים למדודמיד אחרי ההפעלה, תהליכים קבועים עדיין פעילים

איור 8: מתחילים למדוד רק אחרי שהפעולה ברקע נרגעה, אחרי ההפעלה מחדש.

להשוואה קפדנית, משתמשים ב-clean boot

Microsoft מנחה הליך להגעה להרכב הפעלה מינימלי בעזרת clean boot. בשיטה זו, עוצרים שירותים שאינם של Microsoft עם msconfig, ומבטלים את Startup apps ב-Task Manager.

זה חזק לצמצום רעש. אבל זה מתרחק מסביבת השימוש היומיומית, ולכן מתאים לשימוש ב”השוואת מעבדה שרוצה לראות הבדל קוד”.

משתיקים התראות

באנר ההתראות של Windows, גם אם נראה קל, מפריע יותר ממה שנראה. מלבד ההפרעה החזותית, זה עלול לשנות גם תזמון ריצה, פוקוס, ופעילות אפליקציה ברקע.

מפעילים ידנית Do not disturb, או לפחות מכבים התראות בזמן ה-benchmark.

מדכאים אינדקס חיפוש וסנכרון

אם מטרת ה-benchmark מסוג שקורא כמות גדולה של קבצים, כותב תוצרים בכמות גדולה, או בונה מחדש עץ מקור פעמים רבות, אינדקס חיפוש וסנכרון בענן נוגסים בשקט.

  • מוציאים את תיקיית ה-benchmark מהיעד לאינדוקס
  • עוצרים סנכרון של OneDrive /‏ Dropbox /‏ Google Drive וכדומה
  • סוגרים דפדפן,‏ Teams,‏ Discord,‏ Slack

זה לא מרשים, אבל כשזה משפיע — זה משפיע מאוד.

רעש שנוגס ב-benchmark שנוגע בהרבה קבציםתרשים המראה שב-benchmark מסוג שקורא וכותב הרבה קבצים, אינדקס החיפוש, הסנכרון בענן ואפליקציות קבועות נוגסים במדידה, ולכן החרגה או עצירה מצמצמות רעש.אינדקס חיפושנוגס ב-benchmark שנוגע בהרבה קבציםסנכרון ענןאפליקציות קבועותהחרגה ועצירה מצמצמות רעש

איור 9: ככל ש-benchmark קורא וכותב יותר קבצים, עצירת אינדקס וסנכרון משפיעה יותר.

השוואה בלי לתאם חום, בעצם משווה חום

CPU ו-GPU משנים את שעון ההרצה כשהם קרים לעומת אחרי שהתחממו. גם אותו קוד, בכל הרצה התנאים משתנים. זה בולט במיוחד במחשב נייד, מיני מחשב דק, ומחשב שולחני קטן.

המנגנון שבו החום משנה את התנאיםתרשים המראה ש-CPU ו-GPU משנים שעון כשהם קרים לעומת אחרי שהתחממו, ולכן גם אותו קוד משתנה בתנאיו בכל הרצה, ושהשוואה בלי לתאם חום בעצם משווה חום.הרצה במצב קרההתחממות משנה את השעוןהתנאים משתנים בכל הרצההשוואה בלי תיאום חום משווה חום

איור 10: השעון נע לפי החום, ואם לא מתאמים תנאי חום, משווים קירור ולא קוד.

כללים שכדאי לשמור עליהם

  • מתאמים ככל האפשר את טמפרטורת החדר
  • מקבעים את אופן הצבת המחשב הנייד
  • מקבעים את הרכב מתאם ה-AC, המעגן ותצוגות חיצוניות
  • לא עושים עבודה כבדה לפני ה-benchmark
  • מודדים בנפרד את ההרצה הראשונה ואת המצב היציב

הסדר הריצה — לסירוגין

נמנעים מ-A 10 פעמים ואז B 10 פעמים. כי הטיה של חום, מטמון ופעילות ברקע נספגת.

מומלץ אחד מאלה:

  • A B A B A B ...
  • A B B A A B B A ...
  • יוצרים מראש סדר אקראי, ורצים לפיו
סדר ההרצה משנה איך ההטיה נספגתתרשים המראה שאם מריצים קודם את כל A ואז את כל B, ההטיה של חום, מטמון ופעילות ברקע נספגת רק בצד אחד, ואילו ריצה לסירוגין או בסדר אקראי מפזרת את ההטיה לשני הצדדים ומסירה את השפעת הסדר מההבדל.כל A → כל Bההטיה נספגת רק בצד אחדלסירוגין A B A B, או סדר אקראיההטיה מתפזרת לשני הצדדיםהשפעת הסדר מוסרת מההבדל

איור 11: ריצה מרוכזת גוררת גם את ההטיה יחד עם ההשוואה, ולכן רצים לסירוגין או באקראי.

מה שמודדים קובע את המשמעות של “מהיר”

אם דוחסים “מהיר” למספר בודד, בדרך כלל זה נכשל. שלושת המדדים הייצוגיים שכדאי לראות ב-Windows:

1. Wall-clock time (זמן אמיתי)

הזמן שהמשתמש מחכה. זה הקרוב ביותר לחוויית end-to-end, ולכן זה הערך הראשון שבודקים.

ב-Windows, QueryPerformanceCounter‏ (QPC) משמש לקבלת זמן ברזולוציה גבוהה. ב-managed code, בסיסי להשתמש בשרשרת Stopwatch. להסתכל על מילישניות עם DateTime.Now זה קצת חשוף מדי.

2. CPU time (זמן משתמש + זמן ליבה)

הזמן שבו התהליך באמת השתמש ב-CPU, שמתקבל עם GetProcessTimes.

זה נוח לראות יעילות חישוב. לדוגמה, אם wall-clock מהיר יותר אבל CPU time לא השתנה, ייתכן שמטמון, I/O, זמן המתנה או תזמון משפיעים.

3. Cycle count (מספר מחזורי מעבד)

עם QueryProcessCycleTime אפשר לקבל את מספר מחזורי ה-CPU של כל התהליך.

גם זה מדד ל-CPU work, אבל הוא מראה פן אחר מ-wall-clock. נוח במיוחד כשרוצים לראות “האם זמן ההמתנה זהה, אבל חלק החישוב נהיה קל יותר”.

הפן ששלושת המדדים מראיםתרשים המראה ש-wall-clock time מראה כמה המשתמש מחכה, CPU time מראה כמה CPU התהליך באמת השתמש, ו-cycle count מראה כמה כבד חלק החישוב, ורק בשילוב אפשר לקרוא את התוכן של המהירות.בוחנים את תוכן ה'מהיר'wall-clock: זמן המתנהCPU time: זמן CPU בפועלcycle: כובד חלק החישובמנחשים את הסיבה מהשילוב

איור 12: לא דוחסים למספר בודד — קוראים את משמעות המהירות משילוב שלושת המדדים.

priority,‏ affinity,‏ NUMA הם המוצא האחרון

לפעמים אלה משפיעים. אבל אם נוגעים בהם מהתחלה רק כי הם משפיעים, קל ליצור תופעה אחרת.

קודם מודדים רגיל

אם ההבדל מופיע במצב ברירת מחדל, יש ערך בהבדל הזה כשלעצמו. אם ישר מכניסים /high או /affinity, זה מכניס “תנאי שלא קורה ב-Windows בפועל”.

priority ו-affinity הם המוצא האחרוןתרשים המראה שקודם מודדים במצב ברירת מחדל, ואם מופיע הבדל יש בו ערך, ושהזרקת עדיפות או affinity ישר מכניסה תנאי שלא קורה בפועל ב-Windows, ולכן אם משתמשים בכך, זה רק בסוף מתוך מטרה מוגדרת.אם צריך, קובעים מטרהקודם מודדים במצב ברירת מחדלהבדל שמופיע — יש בו ערךהזרקת /high או /affinity ישרמכניסה תנאי שלא קורה בפועלומקבעים כמוצא אחרון

איור 13: עדיפות ו-affinity משמשים אחרי שסיימו מדידה בברירת מחדל, ומתוך מטרה מוגדרת.

אם משתמשים, מבהירים את המטרה

  • ‏/high: רוצים לצמצם הפרעה מתהליכים אחרים
  • ‏/affinity: רוצים לקבע הקצאת CPU להשוואה
  • בקרת NUMA: במחשב גדול, רוצים לתאם גם מיקום זיכרון

הפקודה start של Windows יכולה להפעיל עם ציון priority class ו-affinity mask.

start "" /high /wait myapp.exe --bench case1.json
start "" /affinity F /high /wait myapp.exe --bench case1.json

עם זאת, נמנעים מ-/realtime

/realtime ניתן לשימוש, אבל עדיף לא להשתמש בו. זה נוטה להביא לא לסילוק רעש, אלא ליצירת תקרית אחרת.

נוהל מדידה מומלץ

לאור כל זה, נסכם נוהל שנוח לתפעול בפועל.

נוהל שנוטה למעבדה

  1. מקבעים את יעד ההשוואה
    • commit hash / build number
    • גרסת compiler / runtime
    • Debug /‏ Release
    • קיום לוגים, assert, trace
  2. מקבעים את תנאי המחשב
    • build של Windows
    • גרסת BIOS /‏ UEFI
    • גרסת driver
    • הזנת AC
    • טמפרטורת חדר, אופן הצבה
  3. מקבעים תנאי חשמל
    • קובעים את ה-Power mode
    • מתעדים את ה-Active power plan
  4. מפעילים מחדש
  5. ממתינים כמה דקות לפני ה-benchmark
  6. אם צריך, clean boot
  7. מוסיפים warm-up
  8. מריצים A /‏ B לסירוגין
  9. מבטיחים מספר הרצות
  10. שומרים חציון, מינימום, מקסימום,‏ p95
  11. שומרים raw data
  12. אם ההבדל קטן, לוקחים ETW /‏ WPR

כמה פעמים מריצים

הנה גם הקו המנחה לסעיף 9, “מבטיחים מספר הרצות”. זה לא פתרון סטטיסטי מדויק, אלא נקודה מעשית לעבודה.

מה רוצים לראות קו מנחה למספר הרצות לכל גרסה
רוצים לראות רק חציון, ולוודא הבדל גדול (מעל 10%) 10
רוצים לטעון הבדל של כמה אחוזים. גם רוצים לראות פיזור 30
רוצים לקרוא גם p95 30 ומעלה. ב-20 הרצות, p95 הופך לערך אחד או שניים העליונים בעצמם, ומושפע ישירות מערכים חריגים

זמן הביצוע ניתן לאמוד לפי זמן הרצה בודד × מספר הרצות × מספר גרסאות + warm-up. אם עיבוד של 30 שניות מורץ 30 פעמים לכל אחד מ-A /‏ B, זה מחושב לבערך 35 דקות כולל warm-up. אם זה לא ריאלי, נכון יותר לחתוך את מטרת המדידה לחלק קטן יותר (להוציא רק את השלב הכבד), במקום לצמצם את מספר ההרצות.

אם לא ברור מתי לעצור, הדרך הפשוטה היא להגדיל את מספר ההרצות תוך כדי מעקב אחרי מגמת החציון, ולעצור כשההגדלה כבר לא משנה.

מתי עוצרים את מספר ההרצותתרשים המראה שמגדילים את מספר ההרצות תוך מעקב אחרי מגמת החציון, ועוצרים כשהחציון כבר לא זז גם עם הגדלת המספר - קביעה מעשית למספר הרצות.עדיין זזכבר לא זז גם עם הגדלהמגדילים את מספר ההרצותעוקבים אחרי מגמת החציוןעוצרים כאן

איור 14: גם בלי לקבע מראש את מספר ההרצות, אפשר לעצור בנקודה שהחציון התייצב.

פרטים ששווה לתעד — יעזרו בהמשך

בקובץ ה-CSV או ה-JSON של ה-benchmark, שווה לשמור לפחות את אלה:

timestamp,version,scenario,elapsed_ms,user_ms,kernel_ms,cycles,power_mode,power_plan,ac_or_dc,room_temp_c,notes

אם אפשר, נוח להוסיף גם:

cpu_package_temp_start_c,cpu_package_temp_end_c,affinity_mask,priority_class,windows_build,driver_version

ל-benchmark, לפעמים היכולת לפרש בהמשך חשובה יותר מעצם המדידה.

מסתכלים לא רק על הממוצע, אלא גם על החציון והפיזור

הממוצע נוח, אבל ב-benchmark על Windows הוא נשבר בקלות. רק חדירה בודדת של Defender, התראה אחת, או תהליך אחר שהכה ב-SSD — והממוצע נגרר.

הממוצע נגרר על ידי ערך חריגתרשים המראה שרק רעש בודד של סריקת Defender, התראה או I/O של תהליך אחר גורר את הממוצע, ולכן מתבססים על החציון ומוסיפים p95, p99 ומינימום/מקסימום כדי לקרוא לפי פיזור.רעש בודדהממוצע נגררמתבססים על החציוןמוסיפים גם p95 / p99 ו-min / maxקריאה עמידה יותר לערך חריג

איור 15: הממוצע נשבר מרעש בודד, ולכן קוראים לפי שילוב חציון ופיזור.

השילוב המומלץ הוא:

  • חציון: מסתכלים על זה קודם
  • ‏p95 /‏ p99: בודקים אם ה-tail התדרדר
  • ‏min /‏ max: בודקים איך זה סוטה
  • תרשים קופסה או תרשים פיזור: מועיל כשההבדל קטן

איך קוראים כשמופיע הבדל

הפרשנות של התוצאה קלה יותר כשמסתכלים על שילוב.

מהיר רק ב-wall-clock

ייתכן שיפור ב-I/O, זמן המתנה, מטמון או תזמון.

גם CPU time וגם cycle יורדים

סביר להניח שהמימוש עצמו נעשה קל יותר.

איטי / מהיר רק בפעם הראשונה

זה הבדל cold /‏ warm. חושדים בהפעלה, אתחול, יצירת מטמון,‏ JIT.

נהיה איטי יותר ככל שחוזרים

חושדים בחום, throttling, לחץ זיכרון, פעילות ברקע.

קוראים את הסיבה מתבנית ההבדלתרשים המראה שאם ההבדל הוא רק ב-wall-clock חושדים בהמתנה או I/O, אם גם CPU time יורד חושדים במימוש קל יותר, אם ההבדל רק בפעם הראשונה חושדים ב-cold מול warm, ואם ההרצות המאוחרות איטיות יותר חושדים בחום או פעילות רקע.רק זמן אמיתיגם CPU time יורדרק בפעם הראשונהאיטי בהמשךמסתכלים על תבנית ההבדלהמתנה / I/Oמימוש קל יותרcold / warmחום / פעילות רקע

איור 16: לא ההבדל עצמו, אלא התבנית שבה הוא מופיע, מכוונת לסיבה.

חופרים עד “למה זה מהיר” עם ETW /‏ WPR

כשההבדל קטן, או שהסיבה לא ברורה, הדרך המלכותית היא להתקדם לכלי ETW‏ (Event Tracing for Windows) של Windows.

Windows Performance Recorder‏ (WPR) של Microsoft הוא כלי רישום מבוסס ETW, וכלול ב-Windows ADK. אפשר לרשום יחד CPU,‏ I/O,‏ context switch,‏ page fault ועוד.

ברמה המינימלית, זה נראה כך:

wpr -start CPU -filemode

REM כאן מריצים את ה-benchmark

wpr -stop trace.etl

אחרי פתיחה ב-WPA, הגרפים הראשונים שבודקים בדרך כלל קבועים.

מה רוצים לראות הגרף שפותחים איך קוראים
באיזו פונקציה CPU נצרך CPU Usage (Sampled) ממיינים לפי Weight, ומשווים stack בין A ל-B. מכיוון שזה sampling, תהליכים קצרים כמו DPC /‏ ISR לא תמיד נצפים
למה יש המתנה CPU Usage (Precise) בודקים זמן Ready, זמן המתנה, וסיבת context switch. הבדל של המתנה ל-lock או המתנה ל-I/O מופיע כאן
האם יש חסימה שמקורה בדרייבר DPC/ISR בודקים זמן לפי מודול. אם זה גדול, ההבדל לא בצד היישום מלכתחילה
האם הדיסק משפיע Disk Usage בודקים מספר וגודל פעולות I/O, וזמן שירות

בהשוואה, העיקרון הוא לקחת trace אחד לכל אחד מ-A ו-B, על אותו תרחיש, ולהציג את אותו גרף זה לצד זה. גם עם trace בודד אי אפשר להחליט “האם זה איטי”.

בשלב הזה, אפשר להגיע מ- “‏B מהיר ב-3%” ל- “‏B מקטין המתנה ל-lock וזמן ה-ready יורד” “‏A פותח יותר קבצים ולכן ה-cold start איטי יותר” — לדבר עם סיבה.

מהבדל מספרי בלבד להבדל עם סיבהתרשים המראה שכשההבדל קטן או הסיבה לא ברורה, לוקחים עם WPR trace אחד לכל אחד מ-A ו-B על אותו תרחיש, ומשווים ב-WPA את אותו גרף זה לצד זה, ומגיעים לדבר עם סיבה במקום רק אחוז.ההבדל קטן / הסיבה לא ברורהלוקחים trace ל-A ול-B עם WPRמשווים ב-WPA את אותו גרף זה לצד זהאפשר לדבר עם סיבהtrace בודד לא מספיק להחליט האם איטי

איור 17: כשחופרים עד ETW, “מהיר ב-X%” הופך ל”למה זה מהיר”.

רשימת בדיקה מרוכזת בעמוד אחד

לבסוף, בצורה שאפשר להדביק ישירות למסמך נוהל.

מקבעים

  • קיבעתי את יעד ההשוואה (commit hash / build number / Debug או Release / תנאי build כמו PGO / קיום לוגים ו-assert)
  • במחשב נייד, חיברתי AC
  • קיבעתי את Power mode באפליקציית ההגדרות
  • בדקתי את Active power plan עם powercfg /getactivescheme
  • עצרתי התראות. עצרתי אינדקס חיפוש וסנכרון בענן
  • אם צריך, ביצעתי clean boot
  • הפעלתי מחדש, וחיכיתי כמה דקות לפני שהתחלתי

מריצים

  • הכנסתי warm-up
  • מדדתי בנפרד cold (ראשון) ו-warm (יציב)
  • הרצתי A /‏ B לסירוגין, או בסדר אקראי
  • קבעתי מספר הרצות והרצתי (ראו את הטבלה למעלה)

מתעדים

  • שמרתי raw data של שורה אחת להרצה (‏elapsed_ms /‏ user_ms /‏ kernel_ms /‏ cycles)
  • שמרתי AC או DC,‏ Power mode,‏ GUID של ה-power plan, build של Windows, גרסת driver
  • שמרתי טמפרטורת חדר ומצב הצבה
  • רשמתי גם תנאים שלא קיבעתי

מפרשים

  • בדקתי חציון. לא החלטתי לפי ממוצע בלבד
  • בדקתי p95 /‏ p99 של ה-tail
  • בדקתי min /‏ max לערכים חריגים
  • ניחשתי סיבה משילוב wall-clock /‏ CPU time /‏ cycle
  • כשההבדל קטן, חפרתי עד ETW /‏ WPR

סיכום

בהשוואת תוכנה בין גרסאות ב-Windows, מה שבאמת משפיע הוא לא טריק ראוותני. מה שחשוב הוא נוהג שקט אבל משפיע על שחזוריות מהסוג הבא:

  • קיבוע ותיעוד של AC /‏ Power mode /‏ power plan
  • הפרדה בין cold ל-warm
  • הרצה לסירוגין של A /‏ B
  • בדיקת חציון ופיזור
  • אם צריך, clean boot
  • אם ההבדל קטן, חפירה עד הסיבה עם ETW /‏ WPR

והדבר הכי חשוב הוא לכתוב יחד עם התוצאה מה קיבעתי ומה לא קיבעתי. ‏benchmark הוא גם השוואת מהירות, וגם תיעוד תנאי הניסוי.

דיווח האצה בלי תיעוד תנאים, אחרים לא יכולים לוודא אם משיגים את אותה תוצאה. כי נשארים רק מספרים, ולא נשארת דרך לשחזור. לעומת זאת, אם התנאים כתובים כראוי, גם אם ההבדל קטן, יש בתוצאה ערך אמיתי.

תיעוד התנאים קובע את ערך התוצאהתרשים המראה שדוח האצה בלי תנאים נשארים בו רק מספרים ואחרים לא יכולים לוודא, ואילו דוח עם תנאים כתובים כראוי נשארת בו דרך שחזור, כך שגם הבדל קטן שם יש ערך.דיווח בלי תיעוד תנאיםנשארים רק מספריםאחרים לא יכולים לוודאדיווח עם תנאים כתוביםנשארת דרך שחזורגם הבדל קטן — יש ערך

איור 18: ערך ה-benchmark טמון פחות במספרים ויותר בתיעוד מה קובע ומה לא נקבע.

מקורות

מאמרים עדכניים עם אותן תגיות, להעמקה בנושאים קרובים.

העמודים האלה ממקמים את הנושא בהקשר רחב יותר של שירותים והחלטות.

המאמר קשור ישירות לשירותים הבאים.

שאלות נפוצות

שאלות נפוצות בפניות בנושא המאמר.

מה הסיבות העיקריות לתנודתיות בתוצאות benchmark ב-Windows?
יש גורמים בכמה שכבות: מצב חשמל ו-power plan, חום, עדכונים ברקע, אינדקס חיפוש, סריקת אנטי-וירוס, עדיפות ו-affinity, סדר ההרצה, מצב מטמון. גם באותו מחשב Windows, אם התנאים האלה לא מתואמים, זה בפועל ניסוי אחר. בפרט במחשב נייד, ההתנהגות משתנה מאוד בין הזנה מ-AC להזנה מסוללה, ולכן חשוב מאוד להשוות תמיד עם AC ולתעד את התנאים.
מה ההבדל בין power mode ל-power plan?
power mode הוא המעבר בין Best power efficiency,‏ Balanced ו-Best performance שבוחרים ב-Power & battery של אפליקציית ההגדרות, שמשפיע על ההגדרות שמאחוריו וגם על התנהגות ה-PPM‏ (Processor Power Management). power plan הוא תוכנית החשמל המסורתית שבודקים ב-powercfg, כמו Balanced או High performance. ב-Windows קיימים שניהם, ולכן בתוצאת benchmark צריך לתעד לפחות שלושה דברים: האם זה AC או סוללה, מהו ה-power mode, ומהו ה-Active power plan.
האם זה תקלה אם תוכנית החשמל High performance לא מוצגת?
כנראה שזו לא תקלה. לפי התיעוד של Microsoft, במכשירים שתומכים ב-Modern Standby מותרות רק Balanced או תוכניות שנגזרות מ-Balanced. כלומר זה מצב רגיל שבו High performance לא מופיע, לפי תכנון הדגם. בנוסף, אם ה-UI של power mode לא ניתן לשינוי, ייתכן שנבחרה custom power plan, ולכן הכי מהיר לנסות לבחור קודם ב-Balanced.
באיזה סדר כדאי להריץ השוואת מהירות בין גרסה A לגרסה B?
כדאי להימנע מלהריץ קודם את כל A ורק אחר כך את B. כי הטיה של חום, מטמון ופעילות ברקע נטענת רק על צד אחד. מריצים לסירוגין A B A B, או לפי סדר אקראי שנוצר מראש. כמו כן, כדאי להפריד בין ההרצה הראשונה הקרה לבין המצב היציב אחרי שהתחמם, ולהסתכל לא רק על הממוצע אלא גם על החציון, p95, מינימום ומקסימום, כדי למנוע מערך חריג לגרור את התוצאה.

פרופיל הכותב

עמוד היכרות עם כותב המאמר.

Go Komura

מנהל KomuraSoft LLC

מתמחה בפיתוח תוכנה עבור Windows, ייעוץ טכני וחקירת תקלות, בעיקר בפרויקטים עם מערכות קיימות ובאגים שקשה לשחזר.

קישורים ציבוריים

חזרה לבלוג