2011-09-30 58 views
3

我遇到了XCreateGC函數性能問題。看起來在幾種情況下工作正常(快速),在其他情況下非常緩慢:)。欲瞭解更多詳情,請看下面的代碼:XCreateGC函數性能

void some_function(int dx, int dy, int sx, int sy, int w, int h, 
       Drawable src, Drawable mask, Drawable dest) 
{ 
     Display *dpy = QX11Info::display(); 
     GC gc = XCreateGC(dpy, src, 0, 0); 
     XSetClipOrigin(dpy, gc, dx - sx, dy - sy); 
     XSetClipMask(dpy, gc, mask); 
     XCopyArea(dpy, src, dest, gc, sx, sy, w, h, dx, dy); 
     XFreeGC(dpy, gc); 
} 

在此先感謝。

+2

您應該考慮到X11是客戶端/服務器體系結構,並且請求被緩衝。也許在某些情況下,'XCreateGC'調用會觸發刷新請求隊列。嘗試在同步模式下運行你的程序,看看它是否仍然很慢(整個應用程序會很慢,有點你只需要測量這個特定的'XCreateGC')。 –

+0

你能向我們展示一個緩慢的功能和一個快速的功能嗎?我們只能推測可能的差異。 ...還有,有什麼辦法來緩存你的GC?或者每次都完全不同?例如。調用some_function兩次不需要*放棄GC並分配另一個,除非你的代碼強加這個需求。 –

回答

1

Xlib性能的關鍵在於瞭解庫何時需要阻塞來自X服務器的回覆。一般來說,創建資源(如GC)不需要阻塞;資源ID在客戶端分配,創建請求只是排隊或發送,而不等待回覆。當Xlib調用最終需要回復時,它將不得不突然停止並等待所有請求完成,獲取所有待處理內容的回覆,最後獲得手頭回復。這將使得一個Xlib函數看起來非常慢,但實際上你可能會看到一大堆以前的函數的代價。儘管如此,XCreateGC不應該阻止回覆,但據我所知。由於完整的發送緩衝區,它可能會被阻塞?也許你有大量的請求,並且在某些時候你的應用程序會阻塞一個完整的套接字緩衝區,直到X服務器能夠趕上並閱讀更多的請求。

無論如何,因爲這個問題是舊的,它可能來不及要求的細節,但我認爲基本的答案是,如果你使用一個探查器,Xlib函數調用可能在堆棧時,當Xlib實際上是等待或者遇到某些之前 Xlib函數調用的後果,或者僅僅是您正在製作的X個請求的數量太多。很可能XCreateGC本身不是問題。

等待X服務器的另一個深奧原因可能是另一個客戶端有一個服務器抓取,它使服務器不能處理來自其他任何人的請求。

的關鍵策略往往是:

  1. 減少X的請求數
  2. 你阻止一個答覆(拇指粗規則之前做盡可能多的,什麼叫XGetSomething將不得不等待所有掛起的請求完成,然後收集所有回覆)

這些都是通常的主要問題,例外的是,當你做一些真正的繁重的操作,如中移動大量的圖像數據,那麼單個操作可能比操作數或往返阻塞更重要。