• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            string

            string
            posts - 27, comments - 177, trackbacks - 0, articles - 0
              C++博客 :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理
             SSE4.2指令集提供了字符串處理指令,詳細用法可參閱intel開發(fā)手冊。現(xiàn)簡單說明一下幾個指令的用法,因為我們一般用c接口來開發(fā)程序,所以我們主要關(guān)注C接口的用法。 
            首先看int _mm_cmpistri ( __m128i a, __m128i b, const int mode); 因為本文講述串匹配,所以我們把mode的值設(shè)為0xc0. 輸入a,b是以0結(jié)尾的字符串。這條指令將返回[0, 16]之間的一個整數(shù)。如果在b的后綴中發(fā)現(xiàn)了a的前綴,這個整數(shù)用來表示這個后綴的位置; 如果沒發(fā)現(xiàn),返回值為16. 例如 a="EFGHX", b="abcdefghABCDEFGH"
                 0123456789ABCDEF(index)
            b = abcdefghABCDEFGH
            a =                    EFGHX
            返回值為12.
            再比如 a="abcde"
            0123456789ABCDEF(index)
            b = abcdefghABCDEFGH
            a = abcde  
            返回值為0.
            如果a="ABCE",則返回值為16.

             __m128i _mm_cmpistrm ( __m128i a, __m128i b, const int mode); 這條指令返回的是mask,不像_mm_cmpistri那樣返回一個值。

            例如 a="abcd", b="abcdefghABCDEabc"
            0123456789ABCDEF(index)
            b = abcdefghABCDEabc
            a = abcd  
            abc
            ret=1000000000000100(1表示本字節(jié)所有位都是1, 即本字節(jié)為0xFF)

            一個很自然的想法就是根據(jù)返回值在文本串中移動(返回n則往后移動n個字符),直到返回值為0. 仔細閱讀glibc中用SSE4.2指令集做的strstr函數(shù),就會發(fā)現(xiàn)他采用了此種方法。 此方法的問題在于每次從文本串中加載16個字節(jié)到sse寄存器時,地址是不對齊的,極大的影響了執(zhí)行效率。怎樣才能保證每次加載時的地址都是對齊的呢?
            我的方法是每次移動16字節(jié),然后從前一個塊(16字節(jié)塊)中找后綴,從后一個塊中找前綴,然后看前面塊的后綴和后面塊的前綴能不能組合成我們要查找的字串。實驗表明此算法要優(yōu)于前一種算法.
            alignStart:
                {
                    if(plen <= 16){
                        shf_indexV = SIMD_LOAD(IndexVector[plen]);
                        __attribute__ ((aligned (16))) char pbuf[16];
                        int i=0, j=0;
                        for(i =0;i<16-plen ;i++){
                            pbuf[i] = 0xff;
                        }
                        for(;i<16;i++)
                            pbuf[i] = pattern[j++];
                        sseiPattern2 = SIMD_LOAD(pbuf);
                    }
                }

                sseiPattern = SIMD_LOADU(pattern);
                sseiWord0 = SIMD_LOAD(sseiPtr) ;
                pref = SEARCH_PRE_F(sseiPattern, sseiWord0);
                ret_z = has_byte_null(sseiWord0); 
                while(!ret_z){
                    //! find out the prefix
                    __m128i postmV2;
                    __m128i flagV;
                    u32 flag16;
                    while(( pref==16)&&( ret_z ==0)){
                        sseiPtr ++;
                        sseiWord0 = SIMD_LOAD(sseiPtr) ;
                        ret_z = has_byte_null(sseiWord0); 
                        pref = SEARCH_PRE_F(sseiPattern, sseiWord0);
                    }
                    if(pref <= 16 - plen){
                        REPORT((((char*)sseiPtr)+pref));
                    }
                    premV = SEARCH_PRE_M(sseiPattern, sseiWord0);
                    sseiPtr ++;
                    sseiWord0 = SIMD_LOAD(sseiPtr) ;
                    postmV = SEARCH_PRE_M(sseiWord0, sseiPattern2);
                    postmV2= bit_reverse(postmV);
                    flagV  = SS_XAND(premV, postmV2);
                    flag16 = SS_GET_MASK(flagV);

                    if(flag16){
                        int idx = bsf(flag16);
                        REPORT((((char*)sseiPtr)-16+idx));
                    }

                    pref = SEARCH_PRE_F(sseiPattern, sseiWord0);
                    ret_z = has_byte_null(sseiWord0); 
                }
            相關(guān)宏的定義如下

            #define SEARCH_PRE_F(s2,s1)   _mm_cmpistri(s2,s1,0x0c) 
            #define SEARCH_PRE_M(s2,s1)   _mm_cmpistrm(s2,s1,_SIDD_UNIT_MASK|_SIDD_CMP_EQUAL_ORDERED)
            #define SIMD_LOAD(p)   _mm_load_si128((__m128i*)(p))   
            #define SIMD_LOADU(p)  _mm_loadu_si128((__m128i*)(p))   
            #define SS_GET_MASK(V) _mm_movemask_epi8(V)
            #define SS_XAND(s1,s2) _mm_and_si128(s1,s2)
            #define bit_reverse(x)  _mm_shuffle_epi8(x,shf_indexV)
            查看源代碼

            只有注冊用戶登錄后才能發(fā)表評論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


            99精品久久精品| 狠狠色丁香久久婷婷综合_中 | 久久综合九色综合欧美就去吻| 成人综合久久精品色婷婷| 欧美日韩精品久久免费| 久久精品国产2020| 久久精品成人免费网站| 久久久久久久久久免免费精品| 国产精品久久久香蕉| 伊人久久精品无码av一区| 香蕉久久一区二区不卡无毒影院 | 国内精品久久久久久久涩爱 | 久久国产午夜精品一区二区三区| 久久这里有精品视频| 欧美成人免费观看久久| 国产精品久久久久久福利漫画 | 久久久久久亚洲AV无码专区| 国产成人精品白浆久久69| 久久久久这里只有精品 | 久久久久精品国产亚洲AV无码| 日日噜噜夜夜狠狠久久丁香五月| 久久综合狠狠色综合伊人| 性做久久久久久久久浪潮| 精品久久久久久无码国产| 久久久精品人妻一区二区三区蜜桃| 99久久久久| 97久久久久人妻精品专区| 人妻无码久久一区二区三区免费| 日本精品久久久久久久久免费| 国产精品久久久亚洲| 中文字幕人妻色偷偷久久| 久久九九久精品国产| 国产精品日韩深夜福利久久| 成人国内精品久久久久一区| 亚洲人成精品久久久久| 一本色道久久综合亚洲精品| 思思久久99热只有频精品66| 亚洲国产精品综合久久一线| 国产精品久久久久a影院| 合区精品久久久中文字幕一区| 亚洲国产天堂久久久久久|