2012-10-29 51 views
0

我在Android應用程序中有一些代碼,當我分析我的應用程序時,它是大部分時間佔用的東西。我試圖優化它,但仍佔用了大部分CPU時間。我想知道如果有人對我如何加快速度有任何想法。這是使用代碼Im的壓縮版本:可以加速這個Java代碼?

輸入:
d是陣列漂浮
一個是陣列漂浮
e是陣列漂浮

輸出:
出爲3的陣列彩車

代碼:

float [] c=new float[3]; 
float [] b=new float[3]; 
float [] out=new float[3]; 

c[0] = a[0] - d[0 * 4 + 3]; 
c[1] = a[1] - d[1 * 4 + 3]; 
c[2] = a[2] - d[2 * 4 + 3]; 

b[0] = c[0]*d[0 * 4 + 0] + c[1]*d[1 * 4 + 0] + c[2]*d[2 * 4 + 0]; 
b[1] = c[0]*d[0 * 4 + 1] + c[1]*d[1 * 4 + 1] + c[2]*d[2 * 4 + 1]; 
b[2] = c[0]*d[0 * 4 + 2] + c[1]*d[1 * 4 + 2] + c[2]*d[2 * 4 + 2];   

out[0] = b[0] * e[0 * 4 + 0] + b[1] * e[0 * 4 + 1] + b[2] * e[0 * 4 + 2] + e[0 * 4 + 3]; 
out[1] = b[0] * e[1 * 4 + 0] + b[1] * e[1 * 4 + 1] + b[2] * e[1 * 4 + 2] + e[1 * 4 + 3]; 
out[2] = b[0] * e[2 * 4 + 0] + b[1] * e[2 * 4 + 1] + b[2] * e[2 * 4 + 2] + e[2 * 4 + 3]; 

對於那些對3D模型動畫的頂點變換感興趣的人。 'out'是變換的頂點,'a'是原始頂點。其餘的數組是骨架聯合信息。

+2

我真的考慮使用,而不是像這樣的陣列明確命名的局部變量。 –

+1

有可能(並且很多人會說,有必要)使它更加簡潔。速度可能可以通過頭髮來改善。如果這佔用了所有的CPU時間,那將是因爲它每秒鐘執行數百萬次,而不是因爲它很慢。 –

+7

你可能會先解釋這段代碼應該做什麼。 –

回答

1

其餘的代碼是做什麼的?這看起來像一小段代碼,所以它應該執行得非常快。你真的有一個性能問題,或者你想讓你的程序根本不消耗CPU嗎?

這就是說,你可以simly預先計算所有那些瑣碎的算術運算:

c[0] = a[0] - d[3]; 
c[1] = a[1] - d[7]; 
c[2] = a[2] - d[11]; 

我不明白您如何訪問d[3]d[7]d[11]不過,因爲d應該是3個元素的數組。

+1

+1詢問剩下的代碼是做什麼的。不錯的編譯器應該用常量來優化所有的算術運算。 –

+0

我修改了問題,以便解釋代碼的用途。它用於3D動畫中的頂點轉換。 – skinhat

0

你可以用這個做的事情不多,所有的操作都是分配和數學的,你沒有實現這些。另外,這些操作已經非常快了......在某種for循環中執行此操作會更有效率,因爲java必須在乘法之前存儲所有這些數字。動態執行效率會更高。

+0

是的,我看不出有什麼辦法來加速它。我想也許有些事我錯過了它可能出現的一些簡單的方程式,但我無法看到它。 – skinhat

0

對於一個零乘法可以簡化爲零,然後刪除添加,但我相信他們的編譯器或熱點已經可以做到這一點。

您可以嘗試memoising防止重新計算的結果。

此外,你可以嘗試使用JCuda卸載這種數學的GPU,但我不知道這是否支持Android。

+1

(旁註)HotSpot在Android上不會有太大的幫助,但編譯時常量並不是它的工作。 –

0

所有編譯時常量將(必須爲)由編譯器進行常量摺疊。你所能做的就是消除臨時數組,而你不用數組。我試過這樣:

public float[] transform2(float[] a, float[] d, float[] e) 
{ 
    float c0,c1,c2; 
    float b0,b1,b2; 
    float [] out=new float[3]; 

    c0 = a[0] - d[0 * 4 + 3]; 
    c1 = a[1] - d[1 * 4 + 3]; 
    c2 = a[2] - d[2 * 4 + 3]; 

    b0 = c0*d[0 * 4 + 0] + c1*d[1 * 4 + 0] + c2*d[2 * 4 + 0]; 
    b1 = c0*d[0 * 4 + 1] + c1*d[1 * 4 + 1] + c2*d[2 * 4 + 1]; 
    b2 = c0*d[0 * 4 + 2] + c1*d[1 * 4 + 2] + c2*d[2 * 4 + 2];   

    out[0] = b0 * e[0 * 4 + 0] + b1 * e[0 * 4 + 1] + b2 * e[0 * 4 + 2] + e[0 * 4 + 3]; 
    out[1] = b0 * e[1 * 4 + 0] + b1 * e[1 * 4 + 1] + b2 * e[1 * 4 + 2] + e[1 * 4 + 3]; 
    out[2] = b0 * e[2 * 4 + 0] + b1 * e[2 * 4 + 1] + b2 * e[2 * 4 + 2] + e[2 * 4 + 3]; 

    return out; 
} 

您的代碼花了35665ms來運行10000000000L迭代。 transform2()花費了20077毫秒,所以它有點低於兩倍。兩種方法都先被加熱,一個[],d []和e []包含隨機浮點數。

我不知道是否有可能通過使out一個參數,而不是裏面的方法分配它來改善的東西,如果out可以在外部保守的,但可能不是在你調用的代碼是可能的。然而,將它作爲第四個參數添加會使其惡化一個數量級:它必須撤消一些HotSpot優化。但是,當你在Android上時,如果可行,你可能會考慮這一點。

這是一個很大的迭代...

+0

謝謝。我試着把c和b變成像你的例子那樣的變量,但是當我分析我的應用時,它並沒有提高那麼多。 – skinhat