• <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++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理
             SSE4.2指令集提供了字符串處理指令,詳細用法可參閱intel開發手冊。現簡單說明一下幾個指令的用法,因為我們一般用c接口來開發程序,所以我們主要關注C接口的用法。 
            首先看int _mm_cmpistri ( __m128i a, __m128i b, const int mode); 因為本文講述串匹配,所以我們把mode的值設為0xc0. 輸入a,b是以0結尾的字符串。這條指令將返回[0, 16]之間的一個整數。如果在b的后綴中發現了a的前綴,這個整數用來表示這個后綴的位置; 如果沒發現,返回值為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表示本字節所有位都是1, 即本字節為0xFF)

            一個很自然的想法就是根據返回值在文本串中移動(返回n則往后移動n個字符),直到返回值為0. 仔細閱讀glibc中用SSE4.2指令集做的strstr函數,就會發現他采用了此種方法。 此方法的問題在于每次從文本串中加載16個字節到sse寄存器時,地址是不對齊的,極大的影響了執行效率。怎樣才能保證每次加載時的地址都是對齊的呢?
            我的方法是每次移動16字節,然后從前一個塊(16字節塊)中找后綴,從后一個塊中找前綴,然后看前面塊的后綴和后面塊的前綴能不能組合成我們要查找的字串。實驗表明此算法要優于前一種算法.
            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); 
                }
            相關宏的定義如下

            #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)
            查看源代碼
            狠狠色婷婷久久综合频道日韩| 亚洲午夜久久久影院| 色8久久人人97超碰香蕉987| 久久人妻无码中文字幕| 亚洲综合精品香蕉久久网| 亚洲AV无一区二区三区久久| 2020久久精品国产免费| 99精品久久久久久久婷婷| 国内精品伊人久久久影院| 国产亚洲色婷婷久久99精品| 精品无码久久久久久久动漫| 99久久国产宗和精品1上映| 国产亚洲精久久久久久无码| 久久精品一区二区影院 | 香蕉久久永久视频| 久久精品国产亚洲AV高清热 | 久久久国产精品亚洲一区| 91精品国产91久久久久久青草 | 久久人人爽人人爽人人片AV高清 | 国产美女亚洲精品久久久综合| 国产韩国精品一区二区三区久久| 亚洲国产成人久久综合一区77 | 久久国产欧美日韩精品| 观看 国产综合久久久久鬼色 欧美 亚洲 一区二区 | 精品熟女少妇a∨免费久久| 欧美久久久久久精选9999| 国产∨亚洲V天堂无码久久久| 欧美麻豆久久久久久中文| 国内精品久久久久影院优 | 日本五月天婷久久网站| 国产午夜电影久久| 色综合久久精品中文字幕首页| 囯产极品美女高潮无套久久久| 久久青青国产| 久久久WWW成人免费毛片| 91亚洲国产成人久久精品网址| 国产婷婷成人久久Av免费高清| 亚洲日韩中文无码久久| 亚洲色婷婷综合久久| 久久久久亚洲精品无码蜜桃| 少妇高潮惨叫久久久久久|