// File: xiangzejun[P]Optimizing_Implementations_of_Linear_Layers/reduce.cpp
// Function: reduce(std::vector<std::bitset<32ul>, std::allocator<std::bitset<32ul>>>)
vector<xpair> reduce(vector<ROW> m)
{

	vector<ROW> tmp_m(m);

	vector<xpair> seq = strgy3(m);
	int l = reduce_step(seq);


	int gap = l;
	int start = 0;

	thread_data data[THREAD_NUM];
	bool flag = true;
	while(flag)
	{
		for(int j = 0; j < THREAD_NUM; j++)
		{
			data[j].seq = seq;
			data[j].gap = gap;
			data[j].start = start;
			if((gap != 3) || (start != l - gap))
			{
				if(start == l - gap)
				{
					gap--;
					start = 0;
				}
				else
				{
					start++;
				}
			}
			else
			{
				flag = false;
			}
		}
		int rc;
		pthread_t threads[THREAD_NUM];
		pthread_attr_t attr;
		void* status;
		pthread_attr_init(&attr);
		pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
		for(int j = 0; j < THREAD_NUM; j++)
		{

			rc = pthread_create(&threads[j], NULL, reduce_thread, (void *)(data + j));
			if(rc)
			{
				cout << "Error: unable to create thread!" << endl;
				exit(-1);
			}
		}
		// pthread_attr_destroy(&attr);
		for(int j = 0; j < THREAD_NUM; j++)
		{
			rc = pthread_join(threads[j], &status);
			if(rc)
			{
				cout << "Error: unable to join, " << rc << endl;
				exit(-1);
			}
		}
		for(int j = 0; j < THREAD_NUM; j++)
		{
			if(data[j].len < l)
			{
				seq = data[j].seq;
				l = data[j].len;
				gap = l;
				start = 0;
			}
		}
		// cout << "gap = " << gap << endl;
	}
	return seq;
}

// Assembly:
subq $0x1f8, %rsp            # imm = 0x1F8
movq %rsi, 0x88(%rsp)
movq %rdi, 0x80(%rsp)
movq %rdi, %rax
movq %rax, 0x78(%rsp)
movq %rdi, 0x1f0(%rsp)
movq %rsi, 0x1e8(%rsp)
leaq 0x1d0(%rsp), %rdi
callq 0x2fc0
movq 0x80(%rsp), %rdi
movq 0x88(%rsp), %rsi
movb $0x0, 0x1cf(%rsp)
callq 0x5030
jmp 0xc2ab
movq 0x80(%rsp), %rdi
callq 0xb5f0
movl %eax, 0x74(%rsp)
jmp 0xc2be
movl 0x74(%rsp), %eax
movl %eax, 0x1b8(%rsp)
movl 0x1b8(%rsp), %eax
movl %eax, 0x1b4(%rsp)
movl $0x0, 0x1b0(%rsp)
leaq 0x110(%rsp), %rax
movq %rax, %rcx
addq $0xa0, %rcx
movq %rcx, 0x60(%rsp)
movq %rax, 0x68(%rsp)
movq 0x68(%rsp), %rdi
movq %rdi, 0x58(%rsp)
callq 0xcb70
movq 0x58(%rsp), %rax
movq 0x60(%rsp), %rcx
addq $0x28, %rax
cmpq %rcx, %rax
movq %rax, 0x68(%rsp)
jne 0xc2fe
movb $0x1, 0x10f(%rsp)
testb $0x1, 0x10f(%rsp)
je 0xc6f2
movl $0x0, 0x108(%rsp)
cmpl $0x4, 0x108(%rsp)
jge 0xc4b1
movq 0x80(%rsp), %rsi
movslq 0x108(%rsp), %rax
leaq (%rax,%rax,4), %rax
leaq 0x110(%rsp,%rax,8), %rdi
callq 0xcb80
jmp 0xc377
movl 0x1b4(%rsp), %ecx
movslq 0x108(%rsp), %rdx
leaq 0x110(%rsp), %rax
imulq $0x28, %rdx, %rdx
addq %rdx, %rax
movl %ecx, 0x18(%rax)
movl 0x1b0(%rsp), %ecx
movslq 0x108(%rsp), %rdx
leaq 0x110(%rsp), %rax
imulq $0x28, %rdx, %rdx
addq %rdx, %rax
movl %ecx, 0x1c(%rax)
cmpl $0x3, 0x1b4(%rsp)
jne 0xc3e0
movl 0x1b0(%rsp), %eax
movl 0x1b8(%rsp), %ecx
subl 0x1b4(%rsp), %ecx
cmpl %ecx, %eax
je 0xc491
movl 0x1b0(%rsp), %eax
movl 0x1b8(%rsp), %ecx
subl 0x1b4(%rsp), %ecx
cmpl %ecx, %eax
jne 0xc47e
movl 0x1b4(%rsp), %eax
addl $-0x1, %eax
movl %eax, 0x1b4(%rsp)
movl $0x0, 0x1b0(%rsp)
jmp 0xc48f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1c0(%rsp)
movl %eax, 0x1bc(%rsp)
jmp 0xc7a2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1c0(%rsp)
movl %eax, 0x1bc(%rsp)
jmp 0xc795
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1c0(%rsp)
movl %eax, 0x1bc(%rsp)
leaq 0x110(%rsp), %rax
movq %rax, 0x48(%rsp)
addq $0xa0, %rax
movq %rax, 0x50(%rsp)
jmp 0xc745
movl 0x1b0(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x1b0(%rsp)
jmp 0xc499
movb $0x0, 0x10f(%rsp)
jmp 0xc49b
movl 0x108(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x108(%rsp)
jmp 0xc346
leaq 0xa8(%rsp), %rdi
callq 0x21a0
leaq 0xa8(%rsp), %rdi
xorl %esi, %esi
callq 0x21c0
movl $0x0, 0x9c(%rsp)
cmpl $0x4, 0x9c(%rsp)
jge 0xc584
movslq 0x9c(%rsp), %rax
leaq 0xe0(%rsp), %rdi
shlq $0x3, %rax
addq %rax, %rdi
leaq 0x110(%rsp), %rcx
movslq 0x9c(%rsp), %rax
imulq $0x28, %rax, %rax
addq %rax, %rcx
xorl %eax, %eax
movl %eax, %esi
leaq -0x45f(%rip), %rdx      # 0xc0c0
callq 0x22c0
movl %eax, 0x104(%rsp)
cmpl $0x0, 0x104(%rsp)
je 0xc56c
movq 0x6a9c(%rip), %rdi      # 0x12fd8
leaq 0x1ce1(%rip), %rsi      # 0xe224
callq 0x2140
movq %rax, 0x40(%rsp)
jmp 0xc54f
movq 0x40(%rsp), %rdi
movq 0x6a6d(%rip), %rsi      # 0x12fc8
callq 0x2170
jmp 0xc562
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
callq 0x2190
jmp 0xc56e
movl 0x9c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x9c(%rsp)
jmp 0xc4d8
movl $0x0, 0x98(%rsp)
cmpl $0x4, 0x98(%rsp)
jge 0xc63c
movslq 0x98(%rsp), %rax
movq 0xe0(%rsp,%rax,8), %rdi
leaq 0xa0(%rsp), %rsi
callq 0x2120
movl %eax, 0x3c(%rsp)
jmp 0xc5c0
movl 0x3c(%rsp), %eax
movl %eax, 0x104(%rsp)
cmpl $0x0, 0x104(%rsp)
je 0xc624
movq 0x69fc(%rip), %rdi      # 0x12fd8
leaq 0x1c61(%rip), %rsi      # 0xe244
callq 0x2140
movq %rax, 0x30(%rsp)
jmp 0xc5ef
movq 0x30(%rsp), %rdi
movl 0x104(%rsp), %esi
callq 0x2280
movq %rax, 0x28(%rsp)
jmp 0xc607
movq 0x28(%rsp), %rdi
movq 0x69b5(%rip), %rsi      # 0x12fc8
callq 0x2170
jmp 0xc61a
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
callq 0x2190
jmp 0xc626
movl 0x98(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x98(%rsp)
jmp 0xc58f
movl $0x0, 0x94(%rsp)
cmpl $0x4, 0x94(%rsp)
jge 0xc6ed
movslq 0x94(%rsp), %rcx
leaq 0x110(%rsp), %rax
imulq $0x28, %rcx, %rcx
addq %rcx, %rax
movl 0x20(%rax), %eax
cmpl 0x1b8(%rsp), %eax
jge 0xc6d5
movq 0x80(%rsp), %rdi
movslq 0x94(%rsp), %rax
leaq (%rax,%rax,4), %rax
leaq 0x110(%rsp,%rax,8), %rsi
callq 0xcb80
jmp 0xc69b
movslq 0x94(%rsp), %rcx
leaq 0x110(%rsp), %rax
imulq $0x28, %rcx, %rcx
addq %rcx, %rax
movl 0x20(%rax), %eax
movl %eax, 0x1b8(%rsp)
movl 0x1b8(%rsp), %eax
movl %eax, 0x1b4(%rsp)
movl $0x0, 0x1b0(%rsp)
jmp 0xc6d7
movl 0x94(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x94(%rsp)
jmp 0xc647
jmp 0xc32d
movb $0x1, 0x1cf(%rsp)
leaq 0x110(%rsp), %rax
movq %rax, 0x18(%rsp)
addq $0xa0, %rax
movq %rax, 0x20(%rsp)
movq 0x20(%rsp), %rdi
addq $-0x28, %rdi
movq %rdi, 0x10(%rsp)
callq 0xce40
movq 0x18(%rsp), %rcx
movq 0x10(%rsp), %rax
cmpq %rcx, %rax
movq %rax, 0x20(%rsp)
jne 0xc712
testb $0x1, 0x1cf(%rsp)
jne 0xc77b
jmp 0xc76e
movq 0x50(%rsp), %rdi
addq $-0x28, %rdi
movq %rdi, 0x8(%rsp)
callq 0xce40
movq 0x48(%rsp), %rcx
movq 0x8(%rsp), %rax
cmpq %rcx, %rax
movq %rax, 0x50(%rsp)
jne 0xc745
jmp 0xc795
movq 0x80(%rsp), %rdi
callq 0x3220
leaq 0x1d0(%rsp), %rdi
callq 0x30c0
movq 0x78(%rsp), %rax
addq $0x1f8, %rsp            # imm = 0x1F8
retq
movq 0x80(%rsp), %rdi
callq 0x3220
leaq 0x1d0(%rsp), %rdi
callq 0x30c0
movq 0x1c0(%rsp), %rdi
callq 0x22a0
nopl (%rax)