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

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

היסטוריית עדכונים (גרסה ראשונה, פורסמה בתאריך 16 Mar 2026)
פרסום ראשון
לצטט את המאמר הזה(DOI (ארכיון רשום): 10.5281/zenodo.22173516)

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

Go Komura (2026). איך משווים נכון מהירות בין גרסאות תוכנה ב-Windows. KomuraSoft LLC. https://comcomponent.com/he/blog/windows-benchmark-comparing-program-versions/

DOI (ארכיון רשום)
10.5281/zenodo.22173516
DOI (הגרסה האחרונה שנרשמה)
10.5281/zenodo.22173517

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

יכול להיות שה-8% האלה הם באמת הבדל בקוד. אבל ב-benchmark על Windows, הסיפור הנפוץ הוא שההבדל הגיע מ-Power mode, Power plan, חום, עדכון ברקע, search indexing, virus scan, affinity, סדר ההרצה או מצב cache. צריך לנטרל את התנאים האלה אחד-אחד.

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

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

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

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

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

מונח משמעות
ETW Event Tracing for Windows. תשתית tracing שכלולה ב-Windows. אפשר לרשום יחד אירועים שמגיעים מ-OS, מ-drivers ומיישומים
WPR / WPA Windows Performance Recorder ו-Windows Performance Analyzer. כלי שרושם traces של ETW, וכלי שפותח ומנתח אותם. שניהם כלולים ב-Windows ADK
clean boot הליך שעוצר services ו-startup apps שאינם של Microsoft, ומאתחל בהרכב מינימלי. משתמשים בו כדי להקטין רעש מתוכנות resident
PGO Profile-Guided Optimization. מנגנון שלוקח סטטיסטיקה של branches וקריאות מהרצה אחת, ומשתמש בה להחלטות אופטימיזציה ב-build הבא. תנאי ה-build משתנים, ולכן זה סעיף לבדיקה אם שני הצדדים באמת בני השוואה
p95 / p99 percentile. כשמסדרים את כל ה-runs מהמהיר לאיטי, הערך שנמצא ב-95% / 99% מלמטה. “אחת מכל 20 הרצות איטית מזה” זה p95
NUMA Non-Uniform Memory Access. ארכיטקטורה שבה המרחק מה-CPU לזיכרון אינו אחיד. מהירות הגישה לזיכרון משתנה לפי ה-node שעליו רצה התוכנית
core parking מנגנון ניהול חשמל שמרדים logical processors שלא בשימוש כשהעומס נמוך

קודם המסקנה

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

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

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

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

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

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

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

ב-diagram, solid line מציינת relation שתמיד מתקיים ו-dashed line מציינת relation מותנה (התנאים מופיעים בהסבר של כל relation ב-detail page). הרשימה המלאה של ה-relations (סה”כ 25, כולל evidence ו-certainty) וההגדרות של ה-concepts המרכזיים נמצאות ב-detail page של ה-knowledge map (ביפנית). Data: JSON-LD / Turtle

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

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

1. השוואה שמחפשת הבדל בקוד

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

במקרה הזה מקטינים ככל האפשר את רעש הסביבה. session ייעודי ל-benchmark, Power mode מקובע, התראות כבויות, דיכוי של search indexing וסנכרון, ואם צריך — גם clean boot.

2. השוואה שמחפשת חוויית משתמש אמיתית

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

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

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

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

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

מה בעיקר מזיז תוצאות ב-Windows

קודם נרכז בגסות מה גורם לתוצאות לקפוץ.

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

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

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

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

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

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

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

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

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

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

שכבה תחתונה: Power planBalancedHigh performancecustom planשכבה עליונה: Power mode - overlayBest power efficiencyBalancedBest performanceאפליקציית Settings — Power mode תחת Power and batteryמעבר עם powercfg /setactiveההגדרה שבאמת פועלת — PPM ותת-קבוצת graphicsחיבור AC או סוללהתקרת תדר / core parking / scaling של ביצועים

איור 4: שתי השכבות — Power mode (overlay) ו-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 בצורה הבאה. ל-plan הפעיל מתווסף * בסוף השורה. בסביבה יפנית, הכותרת ושם ה-plan מופיעים ביפנית.

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

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

  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 (ה-overlay) עצמו. ההליך הרשמי הוא דרך Settings > System > Power & battery באפליקציית Settings.

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

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

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

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

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

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

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

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

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

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

מצמצמים רעש ברקע

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

קודם מאתחלים ומחכים שהמערכת תירגע

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

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

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

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

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

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

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

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

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

מדכאים search indexing וסנכרון

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

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

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

רעש שפוגע ב-benchmark שנוגע בהרבה קבציםתרשים שמראה שב-benchmark שקורא וכותב הרבה קבצים, search indexing, סנכרון ענן ותוכנות resident פוגעים במדידה, ולכן exclusion או עצירה מקטינים רעש.search indexingפוגע ב-benchmark שנוגע בהרבה קבציםסנכרון ענןתוכנות residentexclusion ועצירה מקטינים רעש

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

השוואה בלי ליישר חום בדרך כלל משווה חום

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

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

איור 10: ה-clock זז עם החום. אם לא מיישרים תנאי חום, משווים קירור ולא קוד.

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

  • מיישרים ככל האפשר את טמפרטורת החדר
  • מקבעים איך המחשב הנייד מונח
  • מקבעים את הרכב מתאם ה-AC, ה-dock והמסכים החיצוניים
  • לא עושים עבודה כבדה לפני ה-benchmark
  • מודדים בנפרד את ההרצה הראשונה ואת ה-steady state

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

נמנעים מ-A עשר פעמים ואז B עשר פעמים. חום, cache ופעילות ברקע נצברים אז בצורה מוטה.

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

  • A B A B A B ...
  • A B B A A B B A ...
  • מייצרים מראש סדר אקראי, ורצים לפיו
סדר ההרצה משנה איך ההטיה נצברתתרשים שמראה שאם מריצים קודם את כל A ואז את כל B, הטיה של חום, cache ופעילות ברקע נופלת רק על צד אחד, ואילו הרצה לסירוגין או בסדר אקראי מפזרת את ההטיה לשני הצדדים ומסירה את השפעת הסדר מההבדל.כל 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 (user + kernel)

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

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

3. Cycle count (מספר מחזורי CPU)

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

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

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

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

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

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

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

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

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

איור 13: priority ו-affinity באים אחרי שמסיימים מדידה ב-default, ורק עם מטרה ברורה.

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

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

הפקודה 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, tracing כן/לא
  2. מקבעים את תנאי המחשב
    • Windows build
    • גרסת BIOS / UEFI
    • גרסת driver
    • חיבור AC
    • טמפרטורת חדר, אופן ההצבה
  3. מקבעים תנאי חשמל
    • קובעים את ה-Power mode
    • מתעדים את ה-Active power plan
  4. מאתחלים
  5. מחכים כמה דקות לפני ה-benchmark
  6. אם צריך, clean boot
  7. מוסיפים warm-up
  8. מריצים A / B לסירוגין
  9. דואגים למספר הרצות מספיק
  10. שומרים חציון, min, max, 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 ו-min/max כדי לקרוא לפי פיזור.רעש בודד נכנסהממוצע נמשך הצידהמתבססים על החציוןמוסיפים גם p95 / p99 ו-min / maxקריאה עמידה יותר לערך חריג

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

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

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

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

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

מהיר רק ב-wall-clock

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

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

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

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

זה הבדל cold / warm. חושדים ב-startup, באתחול, ביצירת cache, ב-JIT.

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

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

קוראים את הסיבה מתבנית ההבדלתרשים שמראה שאם ההבדל הוא רק ב-wall-clock חושדים בהמתנה או I/O, אם גם CPU time יורד חושדים במימוש קל יותר, אם ההבדל רק בפעם הראשונה חושדים ב-cold מול warm, ואם ההרצות המאוחרות איטיות יותר חושדים בחום או פעילות ברקע.רק wall-clockגם 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 time, זמן המתנה, וסיבת context switch. הבדל של המתנה ל-lock או ל-I/O מופיע כאן
האם יש חסימה שמקורה ב-driver DPC/ISR בודקים זמן לפי מודול. אם זה גדול, ההבדל מלכתחילה לא בצד היישום
האם הדיסק משפיע Disk Usage בודקים מספר וגודל פעולות I/O, וזמן שירות

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

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

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

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

checklist בעמוד אחד

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

מקבעים

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

מריצים

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

מתעדים

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

מפרשים

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

סיכום

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

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

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

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

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

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

מקורות

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

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

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

שאלות נפוצות

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

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

פרופיל הכותב

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

Go Komura

מנהל KomuraSoft LLC

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

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

חזרה לבלוג