我有一個應用程序被編寫,測試和調試了一個版本爲2.6.x的小型Linux內核。我最近試圖將該項目遷移到基於Debian 3.2.x內核的發行版,並注意到性能下降。我做了一些原始基準測試,發現usleep()的時序差異,函數調用的差異&循環時序等。針對基於Linux 3.2.x和基於2.6.x的系統編譯的代碼之間的戲劇性時序差異
我不確定精確的2.6.x內核配置是什麼(例如,搶佔模型等),我還沒有能夠提取內核構建配置信息 - 我們只是將這個系統作爲我們用於嵌入式應用程序的圖像。對於3.2.x內核,我使用「搶先式內核」配置爲我們的處理器構建了一個優化配置,並刪除了大量完全不需要的可選模塊(像HAM無線設備驅動程序這樣的東西 - 這些東西完全合理地移除)。
我們的系統是一個接近實時的應用程序,它不具有硬實時的要求(我們只需要繼續填充計算數據一定緩衝它被消費之前,這是在固定的速率完成,但是一個可控通過硬件,實際上我們的CPU負載在要求最苛刻的應用程序中保持在30%左右 - 我們有保持緩衝區填充的性能並儘可能地保留空間)。我們使用pthreads,pthread_cond_wait/broadcast等來緩衝狀態信號,控制線程同步等。
首先,介紹一下系統的一些前言。有與圖案許多輪詢線程:
while (threadRunning)
{
CheckSomeStuff();
usleep(polling_interval);
}
而且與像圖案的其他線程:
while (threadRunning)
{
pthread_cond_wait(stuff_needed_condition, some_mutex); // wait on signal
doSomeStuffWhenNeeded();
}
這就是說,我們都注意到在移植的應用程序微妙的時機相關的問題,和算法運行比基於2.6.x內核的系統「慢」很多。
這個簡單的指標是說明:
static volatile long g_foo;
static void setfoo(long foo)
{
g_foo = foo;
}
static void printElapsed(struct timeval t1, struct timeval t2, const char* smsg)
{
double time_elapsed;
time_elapsed = (t2.tv_sec - t1.tv_sec)*1e6 + (t2.tv_usec-t1.tv_usec);
printf("%s elapsed: %.8f\n", smsg, time_elapsed);
}
static void benchmarks(long sleeptime)
{
long i;
double time_elapsed;
struct timeval t1, t2;
// test 1
gettimeofday(&t1, NULL);
for (i=0;i<sleeptime;i++)
{
usleep(1);
}
gettimeofday(&t2, NULL);
printElapsed(t1, t2, "Loop usleep(1)");
// test 2
gettimeofday(&t1, NULL);
usleep(sleeptime);
gettimeofday(&t2, NULL);
printElapsed(t1, t2, "Single sleep");
// test 3
gettimeofday(&t1, NULL);
usleep(1);
gettimeofday(&t2, NULL);
printElapsed(t1, t2, "Single 1us sleep");
// test 4
gettimeofday(&t1, NULL);
gettimeofday(&t2, NULL);
printElapsed(t1, t2, "gettimeofday x 2");
// test 5
gettimeofday(&t1, NULL);
for (i=0;i<n;i++)
{
setfoo(i);
}
gettimeofday(&t2, NULL);
printElapsed(t1, t2, "loop function call");
}
以下是測試結果(是的,輸出小數位是愚蠢的,我知道):
Kernel 2.6.x trial 1:
Loop usleep(1) elapsed: 6063979.00000000
Single sleep elapsed: 100071.00000000
Single 1us sleep elapsed: 63.00000000
gettimeofday x 2 elapsed: 1.00000000
loop function call elapsed: 267.00000000
Kernel 2.6.x trial 2:
Loop usleep(1) elapsed: 6059328.00000000
Single sleep elapsed: 100070.00000000
Single 1us sleep elapsed: 63.00000000
gettimeofday x 2 elapsed: 0.00000000
loop function call elapsed: 265.00000000
Kernel 2.6.x trial 3:
Loop usleep(1) elapsed: 6063762.00000000
Single sleep elapsed: 100064.00000000
Single 1us sleep elapsed: 63.00000000
gettimeofday x 2 elapsed: 1.00000000
loop function call elapsed: 266.00000000
kernel 3.2.65 trial 1:
Loop usleep(1) elapsed: 8944631.00000000
Single sleep elapsed: 100106.00000000
Single 1us sleep elapsed: 96.00000000
gettimeofday x 2 elapsed: 2.00000000
loop function call elapsed: 491.00000000
kernel 3.2.65 trial 2:
Loop usleep(1) elapsed: 8891191.00000000
Single sleep elapsed: 100102.00000000
Single 1us sleep elapsed: 94.00000000
gettimeofday x 2 elapsed: 2.00000000
loop function call elapsed: 396.00000000
kernel 3.2.65 trial 3:
Loop usleep(1) elapsed: 8962089.00000000
Single sleep elapsed: 100171.00000000
Single 1us sleep elapsed: 123.00000000
gettimeofday x 2 elapsed: 2.00000000
loop function call elapsed: 407.00000000
有在walltime巨大的差異之間架起在使用內核2.6.x和內核3.2.x的Linux操作系統上,調用usleep(1)(對於3.2.x爲9秒,對於2.6.x爲6秒)的循環的100,000個循環。爲了記錄,我不認爲我們正在使用呼叫「usleep(1);」代碼庫中的任何地方(但是與任何巨大的應用程序相比,更糟糕的事情可能存在於這裏和那裏),但是這是行爲上的巨大差異。循環中也有很大的不同,它將靜態全局變量設置爲100,000次(3.2時爲400微秒,2.6時爲260微秒)。
我意識到從glibc到編譯器&設置到linux內核配置有多個混淆問題。 Stack Overflow希望得到一些關於從哪裏開始戳的指導。 如果你必須完成這個遷移,你會做什麼?你會考慮哪些因素來解決我們所看到的性能問題?
如需進一步信息,兩個分佈是:
的Puppy Linux - 2.6內核。35-7 SMP未知的內核配置(PREEMPT不過,我敢肯定) - 的glibc 2.6.1 - GCC 4.6.3
Debian的喘息7.7(精簡) - Linux的65年3月2日從定製的內核配置來源 - gcc 4.7.2 - glibc 2.13(Debian EGLIBC 2.13-38 + deb7u6)
首先,您需要描述您是如何得出「算法運行速度慢很多」的結論。這對於某個人有任何決定接下來要看的地方的重要信息。其次,目前還不清楚你爲什麼要睡覺。這可能會或可能不會影響您的問題。這幾乎是一個微觀基準。你的問題聽起來更系統化,因此恕我直言,你應該從更廣泛的系統層面開始,而不是立即縮小到這樣的微觀層面。一旦你提供了更多關於你的「慢」意味着什麼的信息,也許有人可以給出更好的建議。 – kaylum 2015-03-18 22:08:32
在「microbenchmarking」級別上,您將在2.6.x系統上看到100,000次迭代循環需要大約250毫秒,而在3.2.x系統上大約需要400毫秒(單線程進程,空閒系統,以最高優先級運行nicelevel)。 在宏觀層面上,我們看到涉及浮點運算的計算佔用了更多的walltime時間。線程調度在這裏是一個可能的罪魁禍首,但即使對於單線程測試過程,我們也看到相同的計算需要更多的掛鐘時間。 – Walter231 2015-03-19 22:32:10