Android HIDL學(xué)習(xí)(4) ---- 高性能比較(HIDL, FMQ, MMAP)

寫(xiě)在前面

公司一些方案巍杈,在Andoird P上架構(gòu)必須要修改成HIDL颤芬,不然會(huì)遇到一系列的Selinux的問(wèn)題,所以決定還是按照標(biāo)準(zhǔn)的Android HIDL的架構(gòu)重新寫(xiě)了方案(因?yàn)楸容^機(jī)密煎饼,所以不透露具體方案代碼)位岔。但是我們的這個(gè)模塊對(duì)性能的要求非常高,不然咱們的設(shè)備怎么能打敗競(jìng)爭(zhēng)對(duì)手呢牺丙,怎么屹立在世界500強(qiáng)呢则涯,對(duì)吧。_
因?yàn)槲覀冏龅墓I(yè)設(shè)備冲簿,對(duì)實(shí)時(shí)性要求比較高粟判,但是HIDL的設(shè)計(jì)畢竟是需要進(jìn)程間通信來(lái)調(diào)用到比較low level的接口的,肯定會(huì)有一些性能損失峦剔,但是好在還有一些別的機(jī)制來(lái)挽回?fù)p失档礁,本文就來(lái)探討一下這個(gè)問(wèn)題,以及對(duì)不同的方式做一下性能的比對(duì)吝沫。

幾種不同的方式對(duì)比

我們的需求是呻澜,應(yīng)用層需要調(diào)用一些接口到kernel中的驅(qū)動(dòng),有一個(gè)HAL層封裝了對(duì)驅(qū)動(dòng)的操作野舶,應(yīng)用層去調(diào)用HAL層接口易迹,其實(shí)就跟標(biāo)準(zhǔn)的AOSP的模塊類(lèi)似。那么問(wèn)題就來(lái)了平道,以前是直接調(diào)用HAL接口睹欲,然后通過(guò)open/read/write/ioctl來(lái)跟驅(qū)動(dòng)通信就好了,比較關(guān)心性能損耗就是系統(tǒng)調(diào)用到kernel中的時(shí)間損耗一屋,其他都還好窘疮。但是一旦改成HIDL接口的寫(xiě)法,應(yīng)用層就變成了HIDL的client端冀墨,調(diào)用到HAL的server端是用過(guò)binder/hwbinder進(jìn)程間通信完成的闸衫,會(huì)有一些性能的損耗,我們就來(lái)測(cè)一下這個(gè)損耗是多少诽嘉,因?yàn)槲覀兊膽?yīng)用場(chǎng)景對(duì)這個(gè)時(shí)間比較關(guān)心蔚出,所以需要做這些分析弟翘,而且應(yīng)用層會(huì)頻繁的調(diào)用HAL接口。
如果比較難理解的話骄酗,我們來(lái)舉個(gè)例子:
這個(gè)例子是在Android Camera開(kāi)發(fā)過(guò)程中可能遇到的稀余,在camera預(yù)覽過(guò)程中,上層app需要實(shí)時(shí)的獲取camera采集的圖像數(shù)據(jù)趋翻,這個(gè)數(shù)據(jù)量是很大的睛琳,而且這個(gè)過(guò)程也是很復(fù)雜的,因?yàn)樵陬A(yù)覽過(guò)程中還需要調(diào)整ISP進(jìn)行不同效果參數(shù)的調(diào)整踏烙,在這個(gè)過(guò)程中對(duì)camera模塊進(jìn)行控制很頻繁(通過(guò)I2C把數(shù)據(jù)寫(xiě)到camera模組中)师骗。我們假設(shè)要寫(xiě)進(jìn)去的數(shù)據(jù)在應(yīng)用層,需要通過(guò)HAL層接口調(diào)用到驅(qū)動(dòng)中進(jìn)行真正的I2C通信讨惩。


Android HIDL學(xué)習(xí)(4) ---- 高性能比較.jpg

左邊黃色的辟癌,是使用以前的HAL層架構(gòu),直接app進(jìn)程直接function call調(diào)用hall層的函數(shù)步脓,通過(guò)ioctl的system call把數(shù)據(jù)傳送到kernel層愿待。
右邊藍(lán)色的,是使用HIDL來(lái)實(shí)現(xiàn)app調(diào)用底層I2C操作靴患,分為兩部分仍侥,app作為HIDL的client端通過(guò)binder進(jìn)程間通信來(lái)調(diào)用server端的接口。
對(duì)我們而言鸳君,比較關(guān)心的就是proxy client端進(jìn)程間調(diào)用到server端的時(shí)間延遲农渊,畢竟是進(jìn)程間通信,肯定沒(méi)有直接調(diào)用來(lái)的快或颊。而且兩個(gè)不同進(jìn)程砸紊,就涉及到數(shù)據(jù)的拷貝,當(dāng)i2c需要寫(xiě)入的數(shù)據(jù)很大而且調(diào)用次數(shù)很多的時(shí)候這個(gè)拷貝和傳輸?shù)难舆t就會(huì)顯得比較突出了囱挑。
我們這里就使用幾種不同的調(diào)用方式來(lái)看時(shí)間延遲和效率問(wèn)題:

  • 直接調(diào)用
  • HIDL接口傳輸
  • Oneway HIDL interface
    參考代碼:

https://github.com/JayZhang0708/HIDL-4

最終調(diào)用干活的方法
#define LOG_TAG     "Sample#Lib"
#include <log/log.h>
#include <string.h>
#include "sample.h"

int writeMessage(uint8_t *data, int32_t size)
{
    int i;
    uint8_t tmp = 0;
    for(i = 0; i < size; i++) {
        tmp += data[i];
        tmp &= 0xff;
    }

    return tmp;
}

很簡(jiǎn)單醉顽,其實(shí)就是遍歷傳過(guò)來(lái)的數(shù)組。

直接調(diào)用
void test_function_call(void)
{
    android::StopWatch stopWatch("test_function_call");
    writeMessage(buffer, BUFFER_SIZE);
}
HIDL接口傳遞
void test_hidl_interface(void)
{
    SampleMessage message;
    message.size = BUFFER_SIZE;
    message.data.resize(BUFFER_SIZE);
    ::memcpy(&message.data[0], buffer, BUFFER_SIZE);
    android::StopWatch stopWatch("test_hidl_interface");
    benchmark->writeMessage(message);
}
Oneyway HIDL接口
void test_oneway_hidl_interface(void)
{
    SampleMessage message;
    message.size = BUFFER_SIZE;
    message.data.resize(BUFFER_SIZE);
    ::memcpy(&message.data[0], buffer, BUFFER_SIZE);
    android::StopWatch stopWatch("test_oneway_hidl_interface");
    benchmark->writeMessageOneway(message);
}
結(jié)果

04-30 04:14:09.425 29520 29520 D StopWatch: StopWatch test_function_call (us): 1
04-30 04:14:09.426 29520 29520 D StopWatch: StopWatch test_hidl_interface (us): 325
04-30 04:14:09.426 29520 29520 D StopWatch: StopWatch test_oneway_hidl_interface (us): 98
代碼詳細(xì)就不介紹了平挑,之前的幾篇文章都有些游添。
結(jié)果顯而易見(jiàn),直接調(diào)用是很快的通熄,基本沒(méi)有啥lentency唆涝,使用HIDL接口傳輸數(shù)據(jù)會(huì)比較費(fèi)時(shí)間,我們這里傳輸了1000個(gè)byte所以比較明顯唇辨。
然后就是第三個(gè)廊酣,使用了oneway

package vendor.sample.benchmark@1.0;

interface IBenchmark {
    writeMessage(SampleMessage message);
    oneway writeMessageOneway(SampleMessage message);
};

一般來(lái)說(shuō)binder進(jìn)程間通信時(shí)同步的,也就是當(dāng)client調(diào)用接口到server的時(shí)候赏枚,需要server處理結(jié)束亡驰,然后返回給client晓猛。
當(dāng)我們把接口設(shè)置成oneway,就可以把接口的調(diào)用變成異步的凡辱,當(dāng)client調(diào)用接口的時(shí)候鞍帝,系統(tǒng)會(huì)重新起一個(gè)線程來(lái)處理client的函數(shù),調(diào)用接口的線程會(huì)直接返回煞茫。
所以當(dāng)我們有一些接口不需要得到返回值而且不需要block當(dāng)前線程的時(shí)候需要把接口定義為oneway來(lái)提升調(diào)用的效率,當(dāng)然了摄凡,如果你壓根就不考慮性能的話续徽,那就無(wú)所謂啦。

談?wù)剝?nèi)存共享

其實(shí)在用到比較大數(shù)據(jù)傳輸?shù)臅r(shí)候亲澡,最好的選擇是使用內(nèi)存共享來(lái)實(shí)現(xiàn)不同進(jìn)程間的通信钦扭,因?yàn)槭褂脙?nèi)存共享涉及到的代碼比較多,這里就不具體講了床绪,詳細(xì)的話后面有機(jī)會(huì)再單獨(dú)寫(xiě)一篇客情,在Android中如何使用內(nèi)存共享實(shí)現(xiàn)不同進(jìn)程間通信。
比較常見(jiàn)的例子就是Camera的HIDL實(shí)現(xiàn)了癞己,把framebuffer在kernel和應(yīng)用層不同進(jìn)程間進(jìn)行共享膀斋,實(shí)現(xiàn)buffer填充的時(shí)候零拷貝動(dòng)作。最常用的就是使用Android的ION框架來(lái)實(shí)現(xiàn)痹雅。

最后是FMQ

FMQ的出現(xiàn)就是為了解決HIDL接口通信性能差的仰担,我們后面單獨(dú)來(lái)講解Android的FMQ,其實(shí)在瀏覽AOSP原生的代碼中使用FMQ的場(chǎng)景不多绩社,在我自己的使用過(guò)程中摔蓝,我一般用作事件的通知,但是原來(lái)的寫(xiě)法就是使用HIDL 的callback機(jī)制來(lái)實(shí)現(xiàn)愉耙,我嘗試改為FMQ來(lái)實(shí)現(xiàn)贮尉,實(shí)測(cè)下來(lái)效果不是很明顯,但是會(huì)減小系統(tǒng)開(kāi)銷(xiāo)朴沿,不需要頻繁的進(jìn)程間通信了猜谚。
具體可以參考下面鏈接:
https://source.android.com/devices/architecture/hidl/fmq

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市悯仙,隨后出現(xiàn)的幾起案子龄毡,更是在濱河造成了極大的恐慌,老刑警劉巖锡垄,帶你破解...
    沈念sama閱讀 218,682評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件沦零,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡货岭,警方通過(guò)查閱死者的電腦和手機(jī)路操,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)疾渴,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人屯仗,你說(shuō)我怎么就攤上這事搞坝。” “怎么了魁袜?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,083評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵桩撮,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我峰弹,道長(zhǎng)店量,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,763評(píng)論 1 295
  • 正文 為了忘掉前任鞠呈,我火速辦了婚禮融师,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘蚁吝。我一直安慰自己旱爆,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,785評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布窘茁。 她就那樣靜靜地躺著怀伦,像睡著了一般。 火紅的嫁衣襯著肌膚如雪庙曙。 梳的紋絲不亂的頭發(fā)上空镜,一...
    開(kāi)封第一講書(shū)人閱讀 51,624評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音捌朴,去河邊找鬼吴攒。 笑死,一個(gè)胖子當(dāng)著我的面吹牛砂蔽,可吹牛的內(nèi)容都是我干的洼怔。 我是一名探鬼主播,決...
    沈念sama閱讀 40,358評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼左驾,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼镣隶!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起诡右,我...
    開(kāi)封第一講書(shū)人閱讀 39,261評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤安岂,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后帆吻,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體域那,經(jīng)...
    沈念sama閱讀 45,722評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年猜煮,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了次员。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片败许。...
    茶點(diǎn)故事閱讀 40,030評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖淑蔚,靈堂內(nèi)的尸體忽然破棺而出市殷,到底是詐尸還是另有隱情,我是刑警寧澤刹衫,帶...
    沈念sama閱讀 35,737評(píng)論 5 346
  • 正文 年R本政府宣布醋寝,位于F島的核電站,受9級(jí)特大地震影響带迟,放射性物質(zhì)發(fā)生泄漏甥桂。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,360評(píng)論 3 330
  • 文/蒙蒙 一邮旷、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧蝇摸,春花似錦婶肩、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,941評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至啡专,卻和暖如春险毁,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背们童。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,057評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工畔况, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人慧库。 一個(gè)月前我還...
    沈念sama閱讀 48,237評(píng)論 3 371
  • 正文 我出身青樓跷跪,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親齐板。 傳聞我的和親對(duì)象是個(gè)殘疾皇子吵瞻,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,976評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容