מי שמצליח להצדיק את התוצאה הזו מMySQL יזכה בחופשה בקאריבים:
[code lang="sql"]
create table t(a varchar(10));
insert into t(a) values('aaa'),('bbb'),('ccc'),('ddd');
select * from t where a in (666,'a');
+——+
| a |
+——+
| aaa |
| bbb |
| ccc |
| ddd |
+——+
[/code]
C יותר מהירה מJava
כולם יודעים שC יותר מהירה מג'אווה, נכון?
פרוייקטים רציניים של גריסת מספרים (Number crunching) כמו עיבוד תמונה בזמן אמת, זיהוי קול, רינדור, דחיסה, קידוד ווידאו וכו בדרך כלל נכתבים בC (או C++).
בהינתן שתי פיסות קוד שעושות בדיוק את אותו דבר, מעניין לראות את במה מתבטא היתרון של C על ג'אווה.
למה אפשר לצפות ליתרון?
כי ג'אווה רצה מעל JVM, והJVM מוסיף תקורה, ברור שC תרוץ יותר מהר כי היא רצה ישר על הCPU ולא דרך הJVM.
הנה שתי פיסות קוד, אחת בג'אווה ואחת בC. שתי התוכניות מאתחלות שתי מטריצות גדולות ומכפילות אותן אחת בשניה, הקוד בהחלט לא יעיל במיוחד ברמת האלגוריתם, אבל הוא זהה מבחינה מימושית.
הנה הקוד:
תוכנית C:
[code lang="c"]
#include
#include
int main(int argc, char **argv)
{
int i,j,k;
int N = 2500;
printf("N = %d\n", N);
double *A = malloc(N*N*sizeof(double));
double *B = malloc(N*N*sizeof(double));
double *C = malloc(N*N*sizeof(double));
double *bj = malloc(N*sizeof(double));
for (i = 0; i < N; i++)
for (j = 0; j < N; j++)
{
int n = i*N+j;
A[n] = i * j;
}
for (i = 0; i < N; i++)
for (j = 0; j < N; j++)
B[i*N+j] = i * j * j;
// order 7: jik optimized ala JAMA
for (j = 0; j < N; j++) {
for (k = 0; k < N; k++)
bj[k] = B[k*N+j];
for (i = 0; i < N; i++) {
double s = 0;
for (k = 0; k < N; k++) {
s += A[i*N+k] * bj[k];
}
C[i*N+j] = s;
}
}
printf("done\n");
return 0;
}
[/code]
תוכנית ג'אווה:
[code lang="java"]
public class Matrix
{
public static void main(String[] args)
{
int i,j,k;
int N = 2500;
System.err.println("N = " + N);
double A[] = new double[N*N];
double B[] = new double[N*N];
double C[] = new double[N*N];
double bj[] = new double[N];
for (i = 0; i < N; i++)
for (j = 0; j < N; j++)
{
int n = i*N+j;
A[n] = i * j;
}
for (i = 0; i < N; i++)
for (j = 0; j < N; j++)
B[i*N+j] = i * j * j;
// order 7: jik optimized ala JAMA
for (j = 0; j < N; j++) {
for (k = 0; k < N; k++)
bj[k] = B[k*N+j];
for (i = 0; i < N; i++) {
double s = 0;
for (k = 0; k < N; k++) {
s += A[i*N+k] * bj[k];
}
C[i*N+j] = s;
}
}
System.err.println("done");
}
}
[/code]
מי לוקח התערבות של בכמה C עוקפת את ג'אווה בזמן הריצה של זה?
נקמפל ונבדוק:
[code]
$javac Matrix.java
$gcc Matrix.c -o matrix
$ date;java Matrix;date;./matrix;date
Thu Jun 26 08:42:10 IDT 2008
N = 2500
done
Thu Jun 26 08:42:54 IDT 2008
N = 2500
done
Thu Jun 26 08:44:31 IDT 2008
[/code]
לתוכנית בג'אווה לקח לקח 44 שניות ולתוכנית בC לקח 107 שניות.
מש"ל.
אה, רגע. רצינו להראות שC יותר מהירה!
טוב, מסתבר שלא כדאי לקחת דברים כמובנים מאליהם, גם אם כולם יודעים שהם נכונים.
אם אתם חושבים שרימיתי, תריצו בעצמכם. בדקתי על שני מחשבים, אחד עם שתי ליבות של 3GHZ, ואחד עם ארבע ליבות של 2.4GHZ (כמובן שהראשון הוביל בכמה אחוזים טובים, אבל היחס נשמר).
השתמשתי בJava 1.6.06.
לדעתי התופעה הזו נובעת מההתקדמות המדהימה של סביבת הריצה של ג'אווה בתחום הHotspot.
Hotspot היא טכנולוגיה שמקמפלת חלקים "חמים" בתוכנית בזמן, אבל בזמן ריצה. מכיוון שזמינות לHotspot סטטיסטיקות בזמן הריצה הממשי של התוכנית היא יכולה לשנות את הקוד ככה שירוץ בצורה אופטימלית לאור התנהגות של התוכנית ולא כנסיון מלומד לנחש מה יהיה יותר מהר מהתבוננות ושינוי הקוד, מה שעושה קומפיילר סטאטי.
עדכון:
קימפלתי את התוכנית C עם אופטימיזציה מקסימלית והתוצאה שלה השתפרה פלאים:
[code]
gcc -O3 Matrix.c
$ date;./matrix;date
Thu Jun 26 11:26:00 IDT 2008
N = 2500
done
Thu Jun 26 11:26:29 IDT 2008
[/code]
הפעם התוצאה של C היא 29 שניות.
טוב משמעותית מקודם, וגם יותר מהיר בכ30% מג'אווה.
עדכון 2:
שמתי לב שקוד שקומפל עם javac איטי מקוד שקומפל בeclipse. נחשתי שeclipse מקמפל עם jikes (אני לא בטוח בזה).
ניסיתי עם jikes והתוצאה השתוותה, תיקו 29 שניות.
[code]
$ javac Matrix.java ; time java Matrix
N = 2500
done
real 0m42.854s
user 0m55.335s
sys 0m26.214s
$ jikes --bootclasspath /usr/lib/jvm/java-6-sun-1.6.0.06/jre/lib/rt.jar Matrix.java ; time java Matrix
N = 2500
done
real 0m29.463s
user 0m29.366s
sys 0m0.108s
[/code]
אגב, זו תוצאה מדהימה שכדאי שכל מפתח ג'אווה יכיר.
מי רוצה לשפר את התוצאות עוד?
Day of release
בצירוף מקרים קוסמי שחררתי היום גרסאות חדשות לשלושה פרוייקטים בלתי תלויים:
FireStats 1.5.9-RC3:
FireStats 1.5 מתייצב, ורוב הסיכויים שהגרסא הבאה תהיה הגרסא היציבה של הענף הזה.
רשימת השינויים נמצאת כאן.
WPMU Plugin Commander 1.1.0
WPMU Plugin Commander הוא תוסף ניהוי תוספים לWPMU, שמוסיף כמה תכונות מאוד נדרשות לWPMU (אפשרות לבחור איזה תוספים משמשים יכולים להפעיל ולכבות, אפשרות להפעיל אוטומטית תוספים עבור בלוגים חדשים ועוד)
אתמול בלילה קיבלתי תרומת קוד שמוסיפה תמיכה בריבוי שפות לPlugin Commander, וכן שינויי עיצוב שגורמים לא להיות הרבה פחות מכוער.
בנוסף, התורמת של הקוד תרמה גם תרגום לרוסית של התוסף.
Antenna 1.1.0-beta
קיבלתי תרומת קוד גדולה מצוות MTJ, הקוד מממש את הPreprocessor שכתבתי בANTLR 3.0, מה שיאפשר הכנסה של הPreprocesror לתוך MTJ.
MTJ הוא פרוייקט שמטרתו להכניס תמיכה בפיתוח קוד J2ME בEclipse. הפרוייקט יתבסס על EclipseME, שהוא הסטנדרט דה-פקטו לפיתוח J2ME עם Eclipse. הPreprocessor שלי כבר נמצא בתוך EclipseME די הרבה זמן, אבל היתה בעיה עם הרשיון של ANTR 2.7.7 שבו השתמשתי כדי לפתח אותו, ו Eclipse legal לא אישרו את הכנסת הקוד שלי לMTJ מהסיבה הזו.
הצוות של MTJ בחר לבצע Porting של הPreprocessor כך שיעבוד עם ANTLR 3.0 כי הרשיון שלו תואם את זה של Eclipse.
לפני כמה ימים הצוות קיבל אישור מEclipse legal לתת לי את הקוד שהם יצרו כדי שאני אקלוט אותו לתוך Antenna.
הקוד היה איכותי, ועבר את כל בדיקות היחידה שהגדרתי כבר, מה שנתן לי ביטחון גבוה שהוא עובד כמו שצריך. אחרי כמה שעות עבודה, הקוד הוטמע והיום שחררתי גרסא חדשה של Antenna שמשתמשת בPreprocessor החדש כברירת מחדל.
גלויה מסין
יוצא לי לעזור לאנשים בפרוייקטי קוד פתוח שאני מעורב בהם מפעם לפעם, תמיד אני מקבל תודה, אבל אף פעם לא קיבלתי גלויה.
עזרתי לוויליאם בבעיה שהיתה לו בשימוש בAntenna, פרוייקט קוד פתוח שעוזר בתהליך הבניה של ישומי ג'אווה לסלולריים, וקיבלתי גלויה והזמנה לשנחאי :).
The root of all evil
איכות תוכנה נמדדת בכמה פרמטים:
נכונות (correctness): האם התוכנה עושה מה כל מה שהיא צריכה לעשות, ובצורה נכונה?
קלות תחזוקה (maintainability) : כמה קל למצוא ולטפל בבאגים? כמה קל להרחיב את המערכת?
ביצועים (performance) : האם התוכנה עובדת מהר מספיק?
המדדים האלו נוטים לבוא אחד על חשבון השני.
קוד נכון וקל לתחזוקה הוא בדרך כלל פחות יעיל.
קוד נכון ויעיל הוא בדרך כלל קשה לתחזוקה.
קוד יעיל וקל לתחזוקה.. אין דבר כזה :).
שיפור ביצועים בתוכנה הוא אחד הנושאים שכל מפתח מגיע אליו בשלב מסויים. בדרך כלל מוקדם בהרבה ממה שצריך.
הבעיה עם שיפור ביצועים היא שהוא מעלה את מורכבות הקוד, מה שפוגע אוטומטית בקלות התחזוקה, ומעלה את הקושי בשמירה על נכונות.
חכמים ממני כבר אמרו שאופטימיזציה מוקדמת מדי היא שורש כל רע :
כשמשפרים ביצועים מוקדם מדי, קשה להוסיף אחר כך תכונות נוספות לאפליקציה, כי המורכבות של הקוד עולה.
הבעיה היא שגם שכבר מגיע הזמן לשפר ביצועים, רוב המפתחים מבזבזים את הזמן שלהם בשיפורים חסרי ערך שרק מעלים את מורכבות האפליקציה, תוך רווח שולי מאוד בביצועים, לפעמים רווח כל כך שולי שהוא בלתי מורגש.
כשבאים לשפר ביצועים, חשוב להשקיע את הזמן בשיפורים הנכונים.
הדרך הנכונה היא לא להסתכל על הקוד, למצוא פיסת קוד לא יעילה, לשפר אותה ולהכריז שהאפליקציה עובדת יותר מהר.
הדרך הנכונה היא קודם כל לאתר מועמדים לאוטימיזציה, לא לפי איפה שאפשר לעשות אופטימיזציה אלא לפי איפה שצריך והדרך לשם היא למדוד את ביצועי האפליקציה בטיפול במשימות בעייתיות מבחינת ביצועים (בין אם זה יהיה זמן איתחול, פעולה מסויימת בממשק המשתמש שמרגישה איטית או כל דבר אחר).
כשמודדים, חשוב להבין היטב באיזה חלק של הקוד התוכנית מבלה את רוב הזמן, זאת על ידי מדידות של תתי משימות בתוך אותה משימה בעייתית.
ברגע שהבנו את התנהגות האפליקציה ואיתרנו את הגורם או הגורמים לאיטיות, הגיע הזמן לנסות לשפר את הביצועיים.
בשלב הזה רוב המפתחים פשוט ירוצו וישכתבו חלקים מהקוד כדי לגרום להם לרוץ יותר מהר, בדרך כלל תוך העלאת המורכבות של הקוד. הבעיה היא שגם אם אכן יש שיפור ביצועים – איך נחליט אם הוא מצדיק את השינויים שעשינו?
המשמעות של השינויים האלו, היא כאמור עליה במורכבות הקוד, מה שיקשה עלינו להוסיף תכונות עתידיות לקוד ויקשה עלינו לאתר ולתקן באגים.
אולי השיפור בפועל הוא 2% בלבד ולא מצדיק את המחיר הזה?
כדי להחליט צריך להשוות את הביצועים לפני ואחרי השינוי, ולהחליט אם השיפור מצדיק את השינוי בקוד.
הדרך לעשות את זה היא ליצור בדיקה מוגדרת היטב שניתן להריץ שוב ושוב ולקבל מדידות זמן כמעט זהות בין הרצות שונות, ואז לראות בכמה אנחנו מצליחים לשפר את זמן הריצה של הקוד.
כדאי שהבדיקות יריצו בעיקר קוד אמיתי של התוכנית, למפתחים יש נטיה ליצור בדיקות סינטטיות שמראות שיפורי ביצועיים אסטרונומיים בנקודות מסויימת, אבל בתמונה הכללי הרבה פעמים השיפורים הם הרבה פחות משמעותיים.
דוגמא פשוטה:
קוד אמיתי מהתוכנית
[code lang="java"]
// do stuff
doSomething();
// do more stuff
[/code]
בדיקה סינטטית:
[code lang="java"]
int start = time();
for (int i=0;i<1000000;i++)
{
doSomething();
}
int elapsed = time() - start;
print "average time is " + (elapsed / 1000000);
[/code]
צריך לשים שהבדיקה הסינטטית בודקת תזמון של פעולה אחת בזרימה של התוכנית, ויש עוד פעולות (do stuff וdo more stuff). ככה שגם אם נשפר את הביצועים של הבדיקה ב90% - אם הפעולות האחרות לוקחות בסך הכל שניה, וdoSomething לוקחת 10 מילישניות אז השיפור הוא זניח במקרה הזה.
בפוסט הבא בסדרה הזו אני אתאר דוגמא מעשית של אופטימיזציה של שאילתות MySQL
ניהול מלאי חומרה – Inventory
לפני כחודש שאלתי אתכם (קוראי הלא שימושיים בעליל) אם אתם מכירים פיתרון לניהול חומרה.
לא קיבלתי הצעות קונקרטיות.
אז חיפשתי שוב, ומצאתי את Inventory, שנותנת כמעט בדיוק את מה שרציתי.
Inventory כתובה בPHP, ומשוחררת ברשיון GPL.
היא גמישה מאוד, ומאפשרת להגדיר סוגי חומרה כאוות נפשכם, להגדיר ספקים, להגדיר רכיבי חומרה ספיצפיים (ולציין ממי הם ניקנו, מתי, מה אורך האחריות וכו'), ולהרכיב מהם מחשבים.
בנוסף היא תומכת גם בניהול תוכנות ורשיונות, אבל לי אישית זה פחות שימושי.
האפשרות שחסרה לי ביותר שם היא האפשרות להצמיד מסמכים (צילומים של קבלות ותעודות אחריות, צילומים של רכיבי חומרה וכו'), לכל רכיב.
Yubikey
אחרי שהקשבתי לפרק בפודקסט Security now (פודקסט שווה במיוחד לכל מי שמתעניין באבטחת מחשבים), שדיבר על Yubkey, הזמנתי לי אחד מYubico, החברה החדשה שמייצרת אותם.
Yubikey, להלן יוביקי, הוא מתקן USB קטן שדומה לכרטיס זכרון (רק קצת יותר קטן), שמסוגל לייצר סיסמאות חד פעמיות בעזרתם ניתן לאמת את הזהות של מחזיק היוביקי.
הסיסמאות הן חד פעמיות, כך שגם אם מישהו מצותת לתעבורת הרשת שלכם או מתקין keylogger ומצליח לגנוב את הסיסמא, הוא לא יוכל לעשות איתה שום דבר כי היא טובה לפעם אחת בלבד.
את הסיסמא החד פעמית – One time password, להלן OTP (סחפ??) אפשר לאמת מול שרת של יוביקו (שלא צריך לדעת עליכם שום דבר), או בצורה מקומית בסעזרת API פתוח קוד שיוביקו מספקים (מאוכסן בגוגל קוד).
יוביקו מספקים גם שרת openid, שיאפשר לכם להזדהות באמצעות היוביקי שלכם מול כל שרות שתומך בopenid. מכיוון שאני מפעיל בעצמי את שרות הopenid שלי, אני מתכנן לשפצר לתוכו תמיכה ביוביקי.
מה שיפהפה ביוביקי הוא שהוא לא דורש אף תוכנה בצד הלקוח. איך קסם כזה יתכן, אתם שואלים?
פשוט מאוד, היוביקי מתפקד כמקלדת USB עם כפתור אחד. ברגע שאתם לוחצים על הכפתור, הוא משפריץ את הסיסמא החד פעמית (ששונה כמובן מלחיצה ללחיצה) לתוך שדה הטקסט שנמצא כרגע בפוקוס (אם יש כזה).
הסיסמא מורכבת מרצף אותיות אקראי למראה של 44 אותיות (!), כאשר 12 האותיות הראשונות לא משתנה ומהוות את המזהה אל היוביקי שלכם (מספר סידורי).
הנה כמה דוגמאות של סיסמאות שהיוביקי שלי הפיק:
[code]
fjjbrkcettntrcednnvjilthincecdnclchvelvlbjjh
fjjbrkcettnteinribhrhfbhktifvirfrevvcveubekd
fjjbrkcettntntjvkgtelfuilrddhujdrjlnnvkbkivv
[/code]
אפשר לראות שהמזהה שלי הוא fjjbrkcettnt, שהוא כמובן לא סוד גדול (ולמרות זאת אפשר לנחש שהמזהה שלי הוא לא בדיוק זה 🙂 )
היוביקי מחזיק מפתח סודי בתוכו, שמאפשר לו להצפין את המידע בתוך הסיסמא. הצד המוודא מפענח את הסיסמא ובודק שהתוכן שלה הגיוני (ושזו לא סיסמא שהוא כבר ראה בעבר סיסמא חדשה ממנה).
אני עדיין מנסה להבין איך להשתמש בAPI שיוביקו מספקים, זה לא אמור להיות מסובך אבל חסר לי פרט או שניים.
הצעצוע הנחמד הזה, שעוד יהיה לי שימושי בקרוב – עולה 35$ (עד עשר יחידות, מעבר לזה המחיר מתחיל לרדת).
ככה הוא נראה:
וכה הוא נראה בתוך תקע USB, ליד DOK סטנדרטי של סאן-דיסק.
הניתוקים הן מהשפן
אני מחובר לאינטרנט דרך תשתית הכבלים של HOT, ואף פעם זה לא עבד לי יותר מדי טוב.
הבעיה המרכזית שלי היא ניתוקים קצרים – דקה או שתיים בדרך כלל. כל פעם שהתלוננתי הגיע טכנאי חביב, חיבר מנחת שמעלה (??) את עוצמת הדציבלים בקו, או – אם כבר יש מנחת, הוציא אותו.
המשחק בעוצמות עזר בעיקר פסיכולוגית, כי אחריו הרגשתי שאין ניתוקים, עד שקלטתי שבעצם רק נדמה לי ויש גם יש.
במשך הזמן די התרגלתי לבעיה, אבל לאחרונה המצב החריף מאוד.
לפני כחצי שנה הגדרתי את הנתב שלי לשלוח לוגים למחשב בפרוטוקול syslog. מה שאומר שיש לי לוגים של חצי השנה האחרונה מהנתב, שמתלונן בקולניות כל פעם שהוא לא מקבל תגובה מהנתב של הISP (מה שאומר בעצם שהתנתקתי).
עם הזמן התחלתי להסתמך עליו כדי לזהות שאני מנותק, וראיתי עליה משמעותית בכמות הניתוקים.
כל פעם שהתלוננתי לHOT על ניתוק, הם שלחו אותו לבדוק את מצב הנוריות של המודם, שהיו בסדר בדרך כלל כי הניתוקים היו קצרים. ברגע שהבנתי את זה, התחלתי לבדוק בעצמי וראיתי שכל פעם שאני שם לב לניתוק, המודם יודע את זה – מה שאומר ללא ספק שזו בעיה של התשתית/המודם ולא של הנתב.
אני רוצה לציין שהשרות של HOT היה טוב, למרות חוסר היכולת שלהם לפתור את הבעיה, וכל פעם שהתלוננתי הם שלחו טכנאי שהחליף מודם, שיחק בעוצמות ובאופן כללי ניסה לעזור.
הטכנאים גם הגיעו בשעות שנוחות לי (שהן די מוזרות), ובדרך כלל הגיעו בזמן.
בכל אופן, אחד הטכנאים האחרונים שהגיע ניסה להבין מאיפה בדיוק מגיעה ההזנה, ולא כל כך מצא.
זה היה הפעם הראשונה שטכנאי שם לב לזה, וזה בהחלט שימח אותו לדעת שסוף סוף הגיע טכנאי שגם חושב לפני שהוא משחק בעוצמות.
אותו טכנאי החליט שהכי פשוט יהיה להתקין חיבור חדש לכל העסק, ולעקוף את המיסתורין של "מאיפה נכנס הכבל".
גישה מצויינת לדעתי, והחלטתי שאני נותן לHOT צ'אנס לתקן את הבעיה ככה לפני שאני עובר סופית לADSL.
לפני כשבוע הגיעו צמד טכנאים שהתקינו חיבור חדש, ובינתיים, לא שמתי לב לאף ניתוק, למרות שאני עדיין רואה ניתוקים קצרים בנתב, מה שאומר שהבדיקה של הנתב לא מאוד אמינה. (יש לה false positives).
היום התקשרתי להוט כדי לסגור את העניין, מבחינתי שבוע בלי ניתוקים מורגשים זה טוב מספיק.
קיבלתי מהם חודשיים זיכוי, אבל אני בהחלט אשקול לעבור לADSL, שלפחות על פי נסיון העבר שלי היה אמין הרבה יותר.
הגביע הקדוש בHD
המקרן הגיע אתמול.
במילה אחת, ואו.
בשתיים: שיט, ואו.
המקרן, HC4900 של מיצובישי (כן, הם עושים גם מקרנים) הוא מאסיבי יחסית למקרנים מדורות קודמים (XGA, 720p וכו'), ושוקל 5.6 ק"ג.
ככה הוא נראה, שמתי שם קופסא של No more heroes לשם הפרופורציות (וגם כי זה משחק מגניב).
חשוב לציין שהDevil ducky לא מגיע עם המקרן ;).
(אפשר להגדיל את כל התמונות בלחיצה).
נכון לכרגע העסק עדיין לא מותקן כמו שצריך, ויש בלאגן רציני של כבלי חשמל, אודיו ווידאו.
המקרן מונח על השולחן ומקרין על מסך נייד זמני שקיבלתי מאקטיבי – החנות שקניתי ממנה – עד שיגיע המסך שלי.
שימו לב שהוא מונח בגובה של בסיס המסך עליו הוא מקרין.
הדבר הזה מתאפשר תודות לתכונה בשם Lens shift, שמזיזה את העדשה ומשנה את התמונה בצורה כזו שלמרות שהמקרן לא מקרין ישר התמונה המוקרנת היא עדיין ריבועית.
המקרן הזה תומך בLens shift אנכי ואופקי, מה שאומר שאפשר לשים אותו בפינת החדר והוא עדיין יקרין תמונה מרובעת על המסך.
ברגע שאני אקבל את המסך, המתלה וכבל הHDMI באורך עשר מטר, אני אוכל לתלות את המקרן על התקרה, שם הוא ישאר עד שאני אעבור דירה.
הרזולוציה של המקרן היא 1920×1080, שהיא רזולוציה של HD מלא, כמו של סרטי Blue ray, והתמונה חדה במיוחד. אפשר לראות את זה בתמונה הבאה.
ניסיתי שהצילום יצא חד ככל האפשר כדי להעביר את החדות של התמונה המוקרנת.
התמונה קצת חתוכה בכלל בעיה בהגדרות של כרטיס המסך.
ואיך אפשר בלי להציג את הגביע הקדוש, הרי הוא מטריקס ב1920X1080?
ביצועים של פענוח וידאו 1080p בקידוד H264
התחלתי לבדוק איך המחשב בסלון מתמודד עם וידאו של 1920X1080 בקידוד H264 – זה וידאו Full HD שיש בBlueRay, וזה מה שאני ארצה להציג על המקרן (שמתמהמה קצת, אולי היום).
המחשב הוא פנטיום D במהירות שעון של 3Ghz, זכרון של 2GB וכרטיס מסך GeForce 8600 GT 512MB, לכאורה לא אמור להיות קובץ וידאו שיהיה מעבר לכוחותיו.
ניסיתי לנגן עליו עם mplayer קובץ דגימה של Matrix – שישים שניות סרט בקובץ של 70 מגה – והמחשב לא סחב אותו כמו שצריך:
הווידאו זז לאט, והסאונד יצא מסינכרון עם התמונה מהר מאוד.
מחשב שהיה פאר היצירה לפני שנתיים, לא סוחב היום משימה של ניגון וידאו. מי אומר שאין צורך במעבדים יותר חזקים?
לשם הבדיקה, ניסיתי את אותו קובץ במחשב החדש – פנטיום Core-DUO 3Ghz, זכרון 4GB וכרטיס מסך GeForce 9800 GT 512MB והוא סחב אותו יפה מאוד.
אז נראה על פניו שצריך מפלצת רצינית כדי לנגן את הקבצים האלו, יותר מהתפלצון שיש לי בסלון.
נסיון ראשון, הדרייבר של כרטיס המסך:
הבדיקה שלי היתה כשxorg, שרת הX (השרת שאחראי על מערכת החלונות והתצוגה) עבד עם הדרייבר הגנרי vesa ולא עם הדרייבר של NVidia כי היתה לי בעיה עם הדרייבר האחרון שלהם.
ניסיתי את הדרייבר nv, שהוא דרייבר פתוח קוד לכרטיסי NVIDIA שלא תומך בהאצת תלת מימד, ולא היה שיפור.
התקנתי את הדרייבר של NVIDIA במחשב בסלון (ונאלצתי להשתמש בגרסא קודמת שהתקנתי לפני כמה שבועות במחשב החדש), עדיין אין שיפור.
למרות שכרטיסי NVIDIA החדשים מגיעים עם תמיכה בפענוח קבצי וידאו בחומרה – טכנולוגיה בשם PureVideo, הדרייברים שלהם ללינוקס לא תומכים בזה, ולכן אף פרוייקט קוד פתוח ללינוקס לא משתמש ביכולת הזו של החומרה.
אז שימוש בחומרה הזו יורד מהפרק כדי להאיץ את העסק, לפחות עד שNVIDIA ישחררו דרייבר שתומך בזה.
נסיון שני, שדרוג של mplayer:
החבר'ה בערוץ הirc של mplayer נבהלו כשסיפרתי להם על איזו גרסא אני בודק:
[code]
[rsk] same mplayer version's?
[omry] hmm, sec
[rsk] also using svn generally speeds up things compared to RC2.
[rsk] especially if you are using a distro package
[omry] hmm, actually the mplayer on the slower box looks older :MPlayer 1.0rc1-4.1.2 (C) 2000-2006 MPlayer Team
[omry] compared to MPlayer dev-SVN-r25315 on the faster box
[rsk] that's ancient
[rsk] please burn it with fire
[omry] dispatching the nukes 🙂
[/code]
כדי להיות בטוח שאני מריץ את הגרסא הכי מהירה שאפשר, הסרתי את הגרסא המותקנת, הורדתי את הקוד העדכני מsvn, ובניתי אותו חיש מהר.
התקנתי, בדקתי, ועדיין העסק זז לאט מדי על המחשב בסלון.
נסון שלישי, שימוש בכמה ליבות:
זוכרים את עסק הביש שבו גוגל סגרה פרוייקט בגוגל קוד לפני כמה שבועות?
כל העסק הוא בדיוק מסביב לזה, CoreAVC הוא פרוייקט מסחרי שמאפשר שימוש בכמה ליבות כדי לפענח H264 בצורה מהירה. הפרוייקט לא תומך בלינוקס – אבל אנשים במצב דומה לשלי החליטו שהם גורמים לו לעבוד על לינוקס בדרכים עקלקלות.
בכל אופן, להתקין קוד סגור נוסף מעבר לדרייבר של NVIDIA זה דבר שהייתי רוצה להמנע ממנו, במיוחד לאור ההיסטוריה הבעייתית של של הפרוייקט.
נסיון רביעי, נגנים אחרים:
טוב, אז אולי mplayer לא כתוב הכי טוב, ונגן אחר יעשה עבודה יותר טובה.
xine בכלל לא ניגן את הקובץ.
VLC ניגן את הקובץ, אבל נראה שהוא מפיל פריימים בצורה שגורמת לווידאו להראות זוועה כשהמחשב לא סוחב אותו (מציג טוב על המחשב המהיר, קטסטרופה על האיטי).
טוב שיהיה mplayer.
נסיון חמישי ודי:
הרצתי את mplayer עם פרמטר -benchmark, והוא סיפר לי די מהר שהמחשב איטי מדי:
[code]
************************************************
**** Your system is too SLOW to play this! ****
************************************************
Possible reasons, problems, workarounds:
– Most common: broken/buggy _audio_ driver
– Try -ao sdl or use the OSS emulation of ALSA.
– Experiment with different values for -autosync, 30 is a good start.
– Slow video output
– Try a different -vo driver (-vo help for a list) or try -framedrop!
– Slow CPU
– Don't try to play a big DVD/DivX on a slow CPU! Try some of the lavdopts,
e.g. -vfm ffmpeg -lavdopts lowres=1:fast:skiploopfilter=all.
– Broken file
– Try various combinations of -nobps -ni -forceidx -mc 0.
– Slow media (NFS/SMB mounts, DVD, VCD etc)
– Try -cache 8192.
– Are you using -cache to play a non-interleaved AVI file?
– Try -nocache.
[/code]
יופי של הודעת שגיאה.
כדי לשלול בעיה של קול או דרייבר תצוגה איטי, הרצתי את mplayer עם
[code]
mplayer -benchmark -vo null -ao null file.mkv
[/code]
מה שמריץ את הווידאו בלי סאונד ובלי תצוגה – פענוח בלבד – לא היה שיפור.
ניסיתי את ההצעה השניה:
[code]
mplayer -vfm ffmpeg -lavdopts lowres=1:fast:skiploopfilter=all file.mkv
[/code]
פה כבר היה שיפור אדיר – הסרט רץ חלק
לא הרגשתי ירידה באיכות, למרות שאמורה להיות איזו שהיא פגיעה באיכות.
אז נראה שככה אני אריץ את הסרטים מהרזולוציה הזו לעת עתה, המפתחים של mplayer טוענים שהם משפרים את הביצועים שלו בפענוח h264 על בסיס כמעט יומי, גם בהיבט של מיקבול (שימוש בכמה ליבות) וגם בהיבט של שיוף ביטים (פענוח יותר מהיר על כל ליבה). אני אבדוק מדי פעם אם הם שיפרו מספיק כדי שאני אוכל לוותר על הפרמטר הזה.