日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

会员教程翻译:性能和时间

發(fā)布時(shí)間:2025/3/14 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 会员教程翻译:性能和时间 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.



來(lái)自會(huì)員德魯伊: 在討論性能之前,先討論一個(gè)重要的話題:時(shí)間。為了理解代碼中的變化如何影響性能,我們需要一個(gè)排序的指標(biāo)。有許多方法用于時(shí)間例程,一些比另一些合適。在本教程


來(lái)自會(huì)員德魯伊

在討論性能之前,先討論一個(gè)重要的話題:時(shí)間。為了理解代碼中的變化如何影響性能,我們需要一個(gè)排序的指標(biāo)。有許多方法用于時(shí)間例程,一些比另一些合適。在本教程中我們將討論Mach Absolute Time。

為什么是Mach? 時(shí)間例程依賴于所需要測(cè)量的時(shí)間域。某些情況下使用諸如clock()或getrusage()函數(shù)來(lái)做些簡(jiǎn)單的數(shù)學(xué)運(yùn)算就足夠了。如果時(shí)間例程將用于實(shí)際的開(kāi)發(fā)框架之外,可移植性就很重要了。我不使用這些。為什么? 對(duì)于我來(lái)說(shuō),調(diào)試代碼的典型問(wèn)題是: 1) 我只需要在即時(shí)測(cè)試時(shí)使用時(shí)間例程 2) 我不喜歡依賴于多種函數(shù)來(lái)包含不同的時(shí)間域。它們的行為可能不一致 3) 有時(shí)我需要一個(gè)高精度定時(shí)器 歡迎了解mach_absolute_time mach_absolute_time是一個(gè)CPU/總線依賴函數(shù),返回一個(gè)基于系統(tǒng)啟動(dòng)后的時(shí)鐘”嘀嗒”數(shù)。它沒(méi)有很好的文檔定義,但這不應(yīng)該成為使用它的障礙,因?yàn)樵贛AC OS X上可以確保它的行為,并且,它包含系統(tǒng)時(shí)鐘包含的所有時(shí)間區(qū)域。那是否應(yīng)該在產(chǎn)品代碼中使用它呢?可能不應(yīng)該。但是對(duì)于測(cè)試,它卻恰到好處。 使用mach_absolute_time時(shí)需要考慮兩個(gè)因素: 1) 如何獲取當(dāng)前的Mach絕對(duì)時(shí)間 2) 如何將其轉(zhuǎn)換為有意義的數(shù)字 獲取mach_absolute_time 這非常簡(jiǎn)單
  • #include?<stdint.h>??
  • uint64_t?start?=mach_absolute_time();?
  • uint64_t?stop?=mach_absolute_time();??
  • 這樣就可以了。我們通常獲取兩個(gè)值,以得到這兩個(gè)時(shí)間的時(shí)間差。 將mach_absolute_time時(shí)間差轉(zhuǎn)換為秒數(shù) 這稍微有點(diǎn)復(fù)雜,因?yàn)槲覀冃枰@取mach_absolute_time所基于的系統(tǒng)時(shí)間基準(zhǔn)。如下代碼:
  • #include?<stdint.h>?
  • #include<mach/mach_time.h>??
  • //Raw?mach_absolute_times?going?in,difference?in?seconds?out?
  • double?subtractTimes(?uint64_tendTime,?uint64_t?startTime?)?
  • {?
  • uint64_t?difference?=?endTime?-?startTime;?
  • static?double?conversion?=?0.0;?
  • if(?conversion?==?0.0?)?
  • {?
  • mach_timebase_info_data_t?info;?
  • kern_return_t?err?=mach_timebase_info(?&info?);?
  • //Convert?the?timebase?into?seconds?
  • if(?err?==?0??)?
  • conversion=?1e-9?*?(double)?info.numer?/?(double)?info.denom;?
  • }?
  • return?conversion?*?(double)difference;?
  • }??
  • 這里最重要的是調(diào)用mach_timebase_info。我們傳遞一個(gè)結(jié)構(gòu)體以返回時(shí)間基準(zhǔn)值。最后,一旦我們獲取到系統(tǒng)的心跳,我們便能生成一個(gè)轉(zhuǎn)換因子。通常,轉(zhuǎn)換是通過(guò)分子(info.numer)除以分母(info.denom)。這里我乘了一個(gè)1e-9來(lái)獲取秒數(shù)。最后,我們獲取兩個(gè)時(shí)間的差值,并乘以轉(zhuǎn)換因子,便得到真實(shí)的時(shí)間差。 現(xiàn)在我們可能會(huì)想,為什么這比用clock好?看起來(lái)做了更多的事情。確實(shí)是有點(diǎn),這便是為什么它在一個(gè)函數(shù)中。我們只需要傳遞我們的值到函數(shù)中并取得答案。 例子 讓我們寫(xiě)個(gè)例子。下面是完整的代碼清單(包括mach函數(shù))。可以使用gcc mach.c –o mach來(lái)編譯它:
  • #include?<stdio.h>?
  • #include?<stdlib.h>?
  • #include?<stdint.h>?
  • #include?<math.h>?
  • #include<mach/mach_time.h>??
  • //Raw?mach_absolute_times?going?in,difference?in?seconds?out?
  • double?subtractTimes(?uint64_tendTime,?uint64_t?startTime?)?
  • {?
  • uint64_t?difference?=?endTime?-startTime;?
  • static?double?conversion?=?0.0;?
  • if(?conversion?==?0.0?)?
  • {?????????
  • mach_timebase_info_data_tinfo;?????????
  • kern_return_terr?=?mach_timebase_info(?&info?);???????????????????????//Convert?the?timebaseinto?seconds?????????
  • if(err?==?0??)????????????????????????
  • conversion=?1e-9?*?(double)?info.numer?/?(double)?info.denom;?????
  • }??????????
  • return?conversion?*?(double)difference;?
  • }??
  • int?main()?
  • {?
  • inti,?j,?count;?
  • uint64_t?start,stop;?
  • doublecurrent?=?0.0;?
  • doubleanswer?=?0.0;?
  • doubleelapsed?=?0.0;?
  • intdim1?=?256;?
  • intdim2?=?256;?
  • intsize?=?4*dim1*dim2;?
  • //Allocatesome?memory?and?warm?it?up?
  • double?*array?=(double*)malloc(size*sizeof(double));????????
  • for(i=0;i<size;i++)array?=?(double)i;?
  • count=?5;??????
  • for(i=0;i<count;i++)?
  • {???????????????
  • start?=?mach_absolute_time();??????????????????????????????????
  • //dosome?work?
  • for(j=0;j<size;j++){?
  • answer+=?sqrt(array[j]);?
  • }?
  • stop?=mach_absolute_time();?
  • current=?subtractTimes(stop,start);?
  • printf("Timefor?iteration:?%1.12lf?for?answer:?%1.12lf\n",current,?answer);?
  • elapsed+=?current;?
  • }????????
  • printf("\nTotaltime?in?seconds?=?%1.12lf?for?answer:?%1.12lf\n",elapsed/count,answer);?
  • free(array);?
  • return?0;?
  • }??
  • 我們?cè)谶@里做了什么?在這個(gè)例子中,我們有一個(gè)適當(dāng)大小的double數(shù)組,當(dāng)中存放了一些數(shù)字,然后獲取這些數(shù)值的和的開(kāi)方。為了測(cè)試,我們迭代了5次這個(gè)計(jì)算。每次迭代后我們打印花費(fèi)的時(shí)間,并總結(jié)了計(jì)算所需的運(yùn)行時(shí)間。在我的PowerMac G5(2.5)機(jī)器上,我獲得如下結(jié)果:
  • [bigmac:~/misc]?macresearch%?gcc?mach.c?-omach?
  • [bigmac:~/misc]?macresearch%./mach??
  • Time?for?iteration:?0.006717496412for?answer:?89478229.125529855490?
  • Time?for?iteration:?0.007274204955for?answer:?178956458.251062750816?
  • Time?for?iteration:?0.006669191332for?answer:?268434687.376589745283?
  • Time?for?iteration:?0.006953711252for?answer:?357912916.502135872841?
  • Time?for?iteration:?0.007582157340for?answer:?447391145.627681851387??
  • Average?time?in?seconds?=0.007039352258?for?answer:?447391145.627681851387?
  • 注意,在這里我沒(méi)有進(jìn)行優(yōu)化,因?yàn)榫幾g器有方法避開(kāi)這樣的無(wú)腦循環(huán)。另外,這只是一個(gè)例子。如果是真正的代碼,我們會(huì)進(jìn)行優(yōu)化。 好了,這就是這個(gè)例子的兩個(gè)目的。 首先,我使用的數(shù)組大小比我的緩存大。我這樣做的目的是因?yàn)槲覀冃枰⒁獾綌?shù)據(jù)溢出緩存的情況(正如這個(gè)例子一樣,至少在我的系統(tǒng)中是這樣。如果是在MacPro中,不會(huì)出現(xiàn)這種情況)。我們將在以后討論緩存的事宜。當(dāng)然,這是一個(gè)做作的例子,但有一些東西可供思考。其次,你注意到在內(nèi)存分配之前我寫(xiě)了一句注釋,這是什么意思呢? 這在實(shí)際情況下是不需要關(guān)心的事情,因?yàn)閮?nèi)存總是在需要時(shí)已準(zhǔn)備好使用。但當(dāng)做一些小測(cè)試時(shí)來(lái)測(cè)試函數(shù)的性能時(shí),它卻可能是會(huì)影響到測(cè)試結(jié)果的實(shí)際問(wèn)題。 當(dāng)動(dòng)態(tài)分配內(nèi)存時(shí),第一次訪問(wèn)內(nèi)存管理時(shí)會(huì)將其清0(在OS X中不管使用哪種動(dòng)態(tài)分配函數(shù):malloc, calloc…所有內(nèi)存在用戶使用前都會(huì)清0)。內(nèi)存清零是一種安全預(yù)防措施(我們不需要遞交一些包含安全信息的內(nèi)容,如解密密鑰) 清零過(guò)程產(chǎn)生一個(gè)副作用(被系統(tǒng)標(biāo)記為零填充頁(yè)面故障)。所以為了讓我們的計(jì)時(shí)更精確些,我們?cè)谑褂脙?nèi)存之前一次性填充數(shù)據(jù),以確保我們不會(huì)獲取到零填充頁(yè)面故障的處理時(shí)間。 讓我們來(lái)測(cè)試一下,注釋下面這行代碼 for(i=0;i<size;i++) array =(double)i; 為: //for(i=0;i<size;i++) array =(double)i; 再次運(yùn)行測(cè)試
  • [bigmac:~/misc]?macresearch%?./mach?
  • Time?for?iteration:?0.009478866798for?answer:?0.000000000000?
  • Time?for?iteration:?0.004756880234for?answer:?0.000000000000?
  • Time?for?iteration:?0.004927868215for?answer:?0.000000000000?
  • Time?for?iteration:?0.005227029674for?answer:?0.000000000000?
  • Time?for?iteration:?0.004891864428for?answer:?0.000000000000??
  • Average?time?in?seconds?=0.005856501870?for?answer:?0.000000000000?
  • 注意第一次迭代的時(shí)間比后序的時(shí)間多了將近一倍。同時(shí)還需要注意所有的answer都是0。再次說(shuō)明內(nèi)存被清零了。如果我們從堆上獲取了內(nèi)存,我們獲取到的是無(wú)意義的數(shù)值。 最后,但很重要的一點(diǎn)。不要依賴于內(nèi)存的清零操作。很有可能獲取到的內(nèi)存是從一個(gè)靜態(tài)分配區(qū)而來(lái),那么可能會(huì)導(dǎo)致如下這樣的問(wèn)題。 double array[3][3]; 在我的系統(tǒng)上的打印結(jié)果是: -1.99844 -1.29321e-231 -1.99844 -3.30953e-232 -5.31401e+303 0 1.79209e-313 3.3146e-314 0 所以需要特別注意。 原帖地址:http://www.cocoachina.com/bbs/read.php?tid=143473

    轉(zhuǎn)載于:https://www.cnblogs.com/zsw-1993/archive/2013/06/08/4880030.html

    總結(jié)

    以上是生活随笔為你收集整理的会员教程翻译:性能和时间的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。