Thread: improving code length

  1. #1
    Registered User
    Join Date
    Dec 2011
    Posts
    795

    improving code length

    This is my x86-specific memcmp() that works much faster than default (or even the C rendition of the same concept), the only problem is that it occupies a lot of lines.

    Code:
    int asm_memcmp_block (const void *s1, const void *s2, int len)
    {
    	register int retval;
    	
    	asm volatile (
    		      "xorq	%%rbx, %%rbx\n"
    
    
    		      "cmp_8:"
    		      "cmpq	$8, %%rax\n"
    		      "jl	cmp_4\n"
    		      "movq	(%%rsi, %%rbx, 0x8), %%rcx\n"
    		      "movq	(%%rdi, %%rbx, 0x8), %%rdx\n"
    		      "cmpq	%%rcx, %%rdx\n"
    		      "jne	_diff\n"
    		      "addq	$8, %%rbx\n"
    		      "subq	$8, %%rax\n"
    		      "jmp	cmp_8\n"
    		      
    		      "cmp_4:"
    		      "cmpq	$4, %%rax\n"
    		      "jl	cmp_2\n"
    		      "movl	(%%rsi, %%rbx, 0x4), %%ecx\n"
    		      "movl	(%%rdi, %%rbx, 0x4), %%edx\n"
    		      "cmpl	%%ecx, %%edx\n"
    		      "jne	_diff\n"
    		      "addq	$4, %%rbx\n"
    		      "subq	$4, %%rax\n"
    		      "jmp	cmp_4\n"
    		      
    		      "cmp_2:"
    		      "cmpq	$2, %%rax\n"
    		      "jl	cmp_1\n"
    		      "movw	(%%rsi, %%rbx, 0x2), %%cx\n"
    		      "movw	(%%rdi, %%rbx, 0x2), %%dx\n"
    		      "cmpw	%%cx, %%dx\n"
    		      "jne	_diff\n"
    		      "addq	$2, %%rbx\n"
    		      "subq	$2, %%rax\n"
    		      "jmp	cmp_2\n"
    		      
    		      "cmp_1:"
    		      "cmpq	$1, %%rax\n"
    		      "jl	_same\n"
    		      "movb	(%%rsi, %%rbx, 0x1), %%cl\n"
    		      "movb	(%%rdi, %%rbx, 0x1), %%dl\n"
    		      "cmp	%%cl, %%dl\n"
    		      "jne	_diff\n"
    		      "incq	%%rbx\n"
    		      "decq	%%rax\n"
    		      "jmp	cmp_1\n"
    		      
    		      "_same:"
    		      "xorq	%%rcx, %%rcx\n"
    		      "jmp	_out\n"
    
    
    		      "_diff:"
    		      "movq	$1, %%rcx\n"
    		      "jmp	_out\n"
    		      
    		      "_out:"
    		      
    		      : "=c" (retval)
    		      : "S" (s1), "D" (s2), "a" (len)
    		      : "rbx", "rcx", "rdx"
    		      );
    	
    	return retval;
    }
    Does anyone have any suggestions as to shorten and/or improve the code? Perhaps using a macro for each value?

  2. #2
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    Two ideas.

    1. Could you compare the blocks backwards, starting at the end, and thereby not use the b register? (But that might cause alignment problems and wouldn't work if you wanted to have it act more like memcmp and say whether the first different byte is greater or less.)

    2. You could presumably get rid of cmp_4 and cmp_2 without any real loss, since if you do that cmp_1 will only need to compare 7 bytes in the worst case. If you don't want to do that, then cmp_1 can get rid of it's loopback since it's only comparing one byte.

    EDIT: Now that I think about it, cmp_4 and cmp_2 will never loop either.
    Last edited by oogabooga; 03-05-2012 at 01:14 AM.
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  3. #3
    Registered User
    Join Date
    Dec 2011
    Posts
    795
    Thanks, that helped. Also, in addition to those changes, is this code standard C:

    Code:
    int asm_memcmp_block (const void *s1, const void *s2, int len)
    {
        register int retval;    
        
    #define MEMCMP_BLK(x,y) "cmp_"#x":"                            \
                        "cmpq    $"#x", %%rax\n"                   \
                        "jl      cmp_"#y"\n"                       \
                        "movq    (%%rdi, %%rax, "#x"), %%rbx\n"    \
                        "cmpq    (%%rsi, %%rax, "#x"), %%rbx\n"    \
                        "jne     _diff\n"                          \
                        "subq    $"#x", %%rax\n"                   \  
                        "jmp     cmp_"#x"\n"                      
    
    
        asm volatile (
                  MEMCMP_BLK ( 8, 1 )
                  
                  MEMCMP_BLK ( 1, 0 )
    
    
                  "cmp_0:"
                  "xorq    %%rcx, %%rcx\n"
                  "jmp    _out\n"
    
    
                  "_diff:"
                  "movq    $1, %%rcx\n"
                  "jmp    _out\n"
                  
                  "_out:"
                  
                  : "=c" (retval)
                  : "S" (s1), "D" (s2), "a" (len)
                  : "rbx"
                  );
        
        return retval;
    }
    Last edited by memcpy; 03-05-2012 at 10:29 PM.

  4. #4
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    The moment you start using assembly, you're into compiler specific extensions, so no there's nothing standard about it.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  5. #5
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    You could also maybe look into the cmps instruction.
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  6. #6
    'Allo, 'Allo, Allo
    Join Date
    Apr 2008
    Posts
    639
    memcmp also returns a value less than 0 when the data dictates

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. help improving code
    By jamort in forum C++ Programming
    Replies: 5
    Last Post: 05-28-2009, 05:13 PM
  2. Improving Code Interface
    By helloamuro in forum C Programming
    Replies: 20
    Last Post: 05-02-2008, 04:34 AM
  3. Improving my code
    By rwmarsh in forum C++ Programming
    Replies: 14
    Last Post: 07-08-2006, 11:18 AM
  4. Code improving
    By Ideswa in forum Game Programming
    Replies: 6
    Last Post: 04-06-2006, 09:49 AM
  5. Improving code
    By Munkey01 in forum C++ Programming
    Replies: 21
    Last Post: 01-15-2003, 01:36 AM