Войти в систему

Home
    - Создать дневник
    - Написать в дневник
       - Подробный режим

LJ.Rossia.org
    - Новости сайта
    - Общие настройки
    - Sitemap
    - Оплата
    - ljr-fif

Редактировать...
    - Настройки
    - Список друзей
    - Дневник
    - Картинки
    - Пароль
    - Вид дневника

Сообщества

Настроить S2

Помощь
    - Забыли пароль?
    - FAQ
    - Тех. поддержка



Пишет kouzdra ([info]kouzdra)
@ 2011-08-09 13:25:00


Previous Entry  Add to memories!  Tell a Friend!  Next Entry
Удивительное рядом:
К этому обсуждению:
Как ни странно - но вот этот код:

let rec count_fast_tail n m acc =
      if n = m then acc + 1
      else if n < m then acc
      else count_fast_tail (n - m) m (count_fast_tail n (m+1) acc)

camlGil__count_fast_tail_127:
	subl	$8, %esp
.L143:
	cmpl	%ebx, %eax
	jne	.L142
	addl	$2, %ecx
	movl	%ecx, %eax
	addl	$8, %esp
	ret
	.align	16
.L142:
	cmpl	%ebx, %eax
	jge	.L141
	movl	%ecx, %eax
	addl	$8, %esp
	ret
	.align	16
.L141:
	movl	%ebx, 4(%esp)
	movl	%eax, 0(%esp)
	addl	$2, %ebx
	call	camlGil__count_fast_tail_127
.L144:
	movl	%eax, %ecx
	movl	0(%esp), %eax
	movl	4(%esp), %ebx
	subl	%ebx, %eax
	incl	%eax
	jmp	.L143

Работает заметно медленнее, чем этот ужас, летящий на крыльях ночи:

void count1_0(int n, int m)
{
  if (n == m) ++ CNT;
  if (n >  m)
    {
      count1_0 (n - m, m);
      count1_0 (n, m + 1);
    }
}



_Z8count1_0ii:
.LFB34:
	.cfi_startproc
	pushl	%ebp
	.cfi_def_cfa_offset 8
	pushl	%edi
	.cfi_def_cfa_offset 12
	pushl	%esi
	.cfi_def_cfa_offset 16
	pushl	%ebx
	.cfi_def_cfa_offset 20
	subl	$124, %esp
	.cfi_def_cfa_offset 144
	movl	148(%esp), %edx
	movl	144(%esp), %eax
	subl	148(%esp), %eax
	subl	%edx, %eax
	subl	%edx, %eax
	subl	%edx, %eax
	subl	%edx, %eax
	subl	%edx, %eax
	subl	%edx, %eax
	subl	%edx, %eax
	subl	%edx, %eax
	movl	%eax, 44(%esp)
.L99:
	movl	144(%esp), %eax
	cmpl	%eax, 148(%esp)
	je	.L106
	.cfi_offset 3, -20
	.cfi_offset 6, -16
	.cfi_offset 7, -12
	.cfi_offset 5, -8
	jge	.L68
	movl	144(%esp), %edx
	subl	148(%esp), %edx
	movl	%edx, 108(%esp)
	movl	148(%esp), %edx
	leal	(%edx,%edx), %eax
	movl	144(%esp), %edx
	subl	%eax, %edx
	movl	44(%esp), %eax
	movl	%edx, 68(%esp)
	movl	148(%esp), %edx
	movl	%eax, 100(%esp)
	movl	%edx, 72(%esp)
.L98:
	movl	108(%esp), %eax
	cmpl	%eax, 72(%esp)
	je	.L107
	jge	.L72
	movl	100(%esp), %edx
	movl	72(%esp), %eax
	movl	%edx, 88(%esp)
	movl	%eax, 56(%esp)
.L97:
	movl	68(%esp), %edx
	cmpl	%edx, 56(%esp)
	je	.L108
	jge	.L74
	movl	56(%esp), %edx
	movl	68(%esp), %eax
	subl	56(%esp), %eax
	movl	%eax, 104(%esp)
	leal	(%edx,%edx), %eax
	movl	68(%esp), %edx
	subl	%eax, %edx
	movl	88(%esp), %eax
	movl	%edx, 64(%esp)
	movl	56(%esp), %edx
	movl	%eax, 92(%esp)
	movl	%edx, 76(%esp)
.L96:
	movl	104(%esp), %eax
	cmpl	%eax, 76(%esp)
	je	.L109
	jge	.L76
	movl	92(%esp), %edx
	movl	76(%esp), %eax
	movl	%edx, 84(%esp)
	movl	%eax, 52(%esp)
.L95:
	movl	64(%esp), %edx
	cmpl	%edx, 52(%esp)
	je	.L110
	jge	.L78
	movl	64(%esp), %eax
	subl	52(%esp), %eax
	cmpl	%eax, 52(%esp)
	movl	%eax, 96(%esp)
	je	.L79
	jge	.L80
	movl	52(%esp), %edx
	leal	(%edx,%edx), %eax
	movl	64(%esp), %edx
	subl	%eax, %edx
	movl	84(%esp), %eax
	movl	%edx, 40(%esp)
	movl	52(%esp), %edx
	movl	%eax, 80(%esp)
	movl	%edx, 60(%esp)
.L81:
	movl	40(%esp), %edx
	cmpl	%edx, 60(%esp)
	je	.L82
	jge	.L84
	movl	80(%esp), %edx
	movl	60(%esp), %eax
	movl	%edx, 48(%esp)
	movl	%eax, 36(%esp)
.L83:
	movl	40(%esp), %edx
	subl	36(%esp), %edx
	cmpl	%edx, 36(%esp)
	movl	%edx, 32(%esp)
	je	.L85
	jge	.L86
	movl	36(%esp), %edx
	movl	40(%esp), %edi
	leal	(%edx,%edx), %eax
	movl	%edx, %ebp
	subl	%eax, %edi
	movl	48(%esp), %eax
	movl	%eax, 28(%esp)
	.p2align 4,,7
	.p2align 3
.L87:
	cmpl	%edi, %ebp
	je	.L88
	jge	.L90
	movl	28(%esp), %esi
	movl	%ebp, %ebx
	.p2align 4,,7
	.p2align 3
.L89:
	movl	%ebx, 4(%esp)
	addl	$1, %ebx
	movl	%esi, (%esp)
	call	_Z8count1_0ii
	cmpl	%edi, %ebx
	je	.L88
	subl	$1, %esi
	cmpl	%edi, %ebx
	jl	.L89
	.p2align 4,,4
	jmp	.L90
	.p2align 4,,7
	.p2align 3
.L88:
	addl	$1, CNT
	adcl	$0, CNT+4
.L90:
	addl	$1, %ebp
	cmpl	32(%esp), %ebp
	je	.L85
	subl	$1, %edi
	subl	$2, 28(%esp)
	cmpl	32(%esp), %ebp
	jl	.L87
	jmp	.L86
	.p2align 4,,7
	.p2align 3
.L85:
	addl	$1, CNT
	adcl	$0, CNT+4
.L86:
	addl	$1, 36(%esp)
	movl	40(%esp), %edx
	cmpl	%edx, 36(%esp)
	je	.L82
	subl	$3, 48(%esp)
	cmpl	%edx, 36(%esp)
	jl	.L83
	jmp	.L84
	.p2align 4,,7
	.p2align 3
.L82:
	addl	$1, CNT
	adcl	$0, CNT+4
.L84:
	addl	$1, 60(%esp)
	movl	96(%esp), %eax
	cmpl	%eax, 60(%esp)
	je	.L79
	movl	96(%esp), %eax
	subl	$1, 40(%esp)
	subl	$4, 80(%esp)
	cmpl	%eax, 60(%esp)
	jl	.L81
	jmp	.L80
.L79:
	addl	$1, CNT
	adcl	$0, CNT+4
.L80:
	addl	$1, 52(%esp)
	subl	$5, 84(%esp)
	jmp	.L95
.L110:
	addl	$1, CNT
	adcl	$0, CNT+4
.L78:
	addl	$1, 76(%esp)
	subl	$1, 64(%esp)
	subl	$6, 92(%esp)
	jmp	.L96
.L109:
	addl	$1, CNT
	adcl	$0, CNT+4
.L76:
	addl	$1, 56(%esp)
	subl	$7, 88(%esp)
	jmp	.L97
.L106:
	addl	$1, CNT
	adcl	$0, CNT+4
.L68:
	addl	$124, %esp
	.cfi_remember_state
	.cfi_def_cfa_offset 20
	popl	%ebx
	.cfi_restore 3
	.cfi_def_cfa_offset 16
	popl	%esi
	.cfi_restore 6
	.cfi_def_cfa_offset 12
	popl	%edi
	.cfi_restore 7
	.cfi_def_cfa_offset 8
	popl	%ebp
	.cfi_restore 5
	.cfi_def_cfa_offset 4
	ret
.L107:
	.cfi_restore_state
	addl	$1, CNT
	adcl	$0, CNT+4
.L72:
	addl	$1, 148(%esp)
	subl	$9, 44(%esp)
	jmp	.L99
.L108:
	addl	$1, CNT
	adcl	$0, CNT+4
.L74:
	addl	$1, 72(%esp)
	subl	$1, 68(%esp)
	subl	$8, 100(%esp)
	jmp	.L98


То есть я конечно понимаю - очень умные процессоры, очень умные компиляторы - но такая груда кода, полученная в результате применения всего этого интеллекта из простенькой функции (справедливости ради - с ключиком -O2 сишный код выглядит уже вполне разумно и работет примерно с такой же скоростью, но ....)