This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [RFC] Fixing strcmp performance on power7 for unaligned loads.



>> Indeed this seems a better strategy, although I am not convinced it will have
>> much gain by aligning the 'a' source.  The strnlen do take the source alignment
>> in consideration (aligned and unaligned will take the same path), and memcmp
>> implementation will take the unaligned path anyway (since although 'a' is
>> aligned, 'b' won't be).
>>
> You need that to be able to use memcmp as it could segfault by reading
> past end which doesn't happen on aligned case. That is unless
> particular memcmp guarantees it doesn't fault by reading cross-page
> boundary which several implementations do.

POWER7 memcmp won't issue any unaligned load, the 'unaligned' patch will
issue aligned loads with some shift logic.  The snippet I used did not
show any issue in string tests.

> 
> 
>> Using a similar strategy as you did:
>>
>> int __strcmp_power7c (const char *a, const char *b)
>> { 
>>   if (IS_ALIGN(a, 8) && IS_ALIGN(b, 8))
>>     return __strcmp_power7 (a, b);
>>    
>>   while (1)
>>     {
>>        size_t len = __strnlen_power7 (b, 64);
>>        if (len != 64)
>>          {
>>            return __memcmp_power7 (a, b, len + 1);
>>          }
>>
>>        int ret = __memcmp_power7 (a, b, 64);
>>        if (ret)
>>          return ret;
>>        a+=64; 
>>        b+=64;
>>     }
>> } 
>>
> 
> And as strncmp I was tired when I wrote previous mail so implementation
> is following, bug was that I forgot to consider checking null in limit.
> 
> int __strncmp_power7b (char *a, char *b, size_t l)
> { 
>   size_t len;
>   int ret;
>   if (l==0)
>     return 0;
>   l--;
>   len = strnlen (a, l < 64 ? l : 64);
>   len = strnlen (b, len);
>   if (len != 64)
>     { 
>       return memcmp (a, b, len + 1);
>     } 
>   ret = memcmp (a, b, 64);
>   if (ret) 
>     return ret;
>   
>   const char *a_old = a;
>   a = ALIGN_DOWN (a + 64, 64);
>   b += a - a_old;
>   l -= a - a_old;
>   while (1)
>     {  
>        len = strnlen (b, l < 64 ? l : 64);
>        if (len != 64)
>          { 
>            return memcmp (a, b, len + 1);
>          }
>        
>        ret = memcmp (a, b, 64);
>        if (ret) 
>          return ret;
>        a+=64;
>        b+=64;
>        l -= 64;
>     }
> }
> 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]