Re: OGR-NG new x86 testing core

Konrad Rzepecki <[email protected]> Mon, 10 Sep 2012 16:54:43 +0200
Newsgroups gmane.comp.distributed-net.hardware
Message-ID <3386305.TRi7i2SPxh@hannibal>
--nextPart149716847.PGV5MnnxLd
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset="utf-8"

Dnia pi=C4=85tek, 31 sierpnia 2012 21:18:08 Konrad Rzepecki pisze:

> I try to write completely different core with use of AVX mnemonics an=
d one
> pass shift.=20

This is my next try. It's only 1-2% faster than original in "-bench" on=
 idle=20
system, but I seems be faster ~5% on busy system.

It have unrolled lzcnt loop. Some register change allow to free ebx. It=
 is now=20
used as "depth" instead of stack variable.

There is also commented out alternate shift method - using vperm2f128 i=
nstead=20
of vextractf128 but is seems to be significant slower.


Did you test 32bit choose table? I try it once and it seems speedup my =
core by=20
1-2%.

--=20
  Konrad Rzepecki (Hannibal)
--nextPart149716847.PGV5MnnxLd
Content-Disposition: attachment; filename="dnetc_ogr_x86_8core_2.diff"
Content-Transfer-Encoding: 7Bit
Content-Type: text/x-patch; charset="UTF-8"; name="dnetc_ogr_x86_8core_2.diff"

diff -ruN client-new3a/common/core_ogr_ng.cpp client-new3c/common/core_ogr_ng.cpp
--- client-new3a/common/core_ogr_ng.cpp	2012-01-17 00:28:37.000000000 +0100
+++ client-new3c/common/core_ogr_ng.cpp	2012-08-30 15:29:32.000000000 +0200
@@ -71,6 +71,7 @@
       CoreDispatchTable *ogrng_get_dispatch_table_cj1_sse_k8(void);  //F (asm #5)
       CoreDispatchTable *ogrng_get_dispatch_table_cj1_sse41(void);  //G (asm #6)
       CoreDispatchTable *ogrng_get_dispatch_table_cj1_sse2_lzcnt(void);  //H (asm #7)
+      CoreDispatchTable *ogrng_get_dispatch_table_d_avx_lzcnt(void);  //I (asm #8)
     #endif
 #elif (CLIENT_CPU == CPU_ARM)
     CoreDispatchTable *ogrng_get_dispatch_table(void);
@@ -116,6 +117,7 @@
           ogrng_get_dispatch_table_cj1_sse_k8();
           ogrng_get_dispatch_table_cj1_sse41();
           ogrng_get_dispatch_table_cj1_sse2_lzcnt();
+          ogrng_get_dispatch_table_d_avx_lzcnt();
         #endif
         #endif
       #elif (CLIENT_CPU == CPU_POWERPC) || (CLIENT_CPU == CPU_CELLBE)
@@ -217,6 +219,7 @@
       "cj-asm-sse-k8",
       "cj-asm-sse4.1",
       "cj-asm-sse2-lzcnt",
+      "d-asm-avx-lzcnt",
       #endif
   #elif (CLIENT_CPU == CPU_AMD64)
       "FLEGE-64 2.0",
@@ -332,6 +335,8 @@
 #  if defined(HAVE_I64)
 #    if (SIZEOF_LONG < 8)   /* classic x86-32 */
        unsigned feature = GetProcessorFeatureFlags();
+       if (cindex == 8 && !(feature & CPU_F_AVX)) /* Core 8 needs AVX */
+         cindex = 7; /* If no AVX, try LZCNT */
        if (cindex == 7 && !(feature & CPU_F_LZCNT)) /* Core 7 needs LZCNT */
          cindex = 3; /* If no LZCNT, try SSE2 */
        if (cindex == 6 && !(feature & CPU_F_SSE4_1)) /* Core 6 needs SSE4.1 */
@@ -432,6 +437,11 @@
         cindex = 1;  /* 64-bit core */
       #else
         #if defined(HAVE_I64)
+          /* Assume AVX is the best for all CPUs which support it? */
+          if (cindex == -1 && detected_flags & CPU_F_AVX)
+          {
+            cindex = 8;
+          }
           /* Assume LZCNT is the best for all CPUs which support it? */
           if (cindex == -1 && detected_flags & CPU_F_LZCNT)
           {
@@ -622,6 +632,8 @@
       unit_func.ogr = ogrng_get_dispatch_table_cj1_sse41();
     else if (coresel == 7)
       unit_func.ogr = ogrng_get_dispatch_table_cj1_sse2_lzcnt();
+    else if (coresel == 8)
+      unit_func.ogr = ogrng_get_dispatch_table_d_avx_lzcnt();
   #endif
     else
       unit_func.ogr = ogrng_get_dispatch_table();
diff -ruN client-new3a/configure client-new3c/configure
--- client-new3a/configure	2012-01-03 18:46:33.000000000 +0100
+++ client-new3c/configure	2012-08-17 13:59:49.000000000 +0200
@@ -250,6 +250,7 @@
         TARGET_ADDSRCS="$TARGET_ADDSRCS $OGR/x86/ogrng-cj1-sse-k8.cpp"
         TARGET_ADDSRCS="$TARGET_ADDSRCS $OGR/x86/ogrng-cj1-sse41.cpp"
         TARGET_ADDSRCS="$TARGET_ADDSRCS $OGR/x86/ogrng-cj1-sse2-lzcnt.cpp"
+        TARGET_ADDSRCS="$TARGET_ADDSRCS $OGR/x86/ogrng-d-avx-lzcnt.cpp"
         TARGET_ADDSRCS="$TARGET_ADDSRCS $OGRNG_GENERAL_SRCS"
         TARGET_ADDNASMS="$TARGET_ADDNASMS $OGR/x86/ogrng-a-asm-rt.asm"
         TARGET_ADDNASMS="$TARGET_ADDNASMS $OGR/x86/ogrng-b-asm-rt.asm"
@@ -258,6 +259,7 @@
         TARGET_ADDNASMS="$TARGET_ADDNASMS $OGR/x86/ogrng-cj1-sse-k8-asm.asm"
         TARGET_ADDNASMS="$TARGET_ADDNASMS $OGR/x86/ogrng-cj1-sse41-asm.asm"
         TARGET_ADDNASMS="$TARGET_ADDNASMS $OGR/x86/ogrng-cj1-sse2-lzcnt-asm.asm"
+        TARGET_ADDNASMS="$TARGET_ADDNASMS $OGR/x86/ogrng-d-avx-lzcnt-asm.asm"
       fi
     fi # HAVE_OGR
 
diff -ruN client-new3a/ogr/ansi/ogrng.h client-new3c/ogr/ansi/ogrng.h
--- client-new3a/ogr/ansi/ogrng.h	2009-09-17 22:16:00.000000000 +0200
+++ client-new3c/ogr/ansi/ogrng.h	2012-08-31 20:06:18.000000000 +0200
@@ -84,7 +84,7 @@
 ** To record the entire core state, we have to store the datas of every level,
 ** plus eight words (assumed to be 64-bit wide each) for ancillary datas.
 */
-#define OGRNG_PROBLEM_SIZE (32 * 4 * OGR_MAXDEPTH + 8 * 8)
+#define OGRNG_PROBLEM_SIZE (256 * OGR_MAXDEPTH + 8 * 8)
 
 
 /*-----------------------------------------------------------------------------
diff -ruN client-new3a/ogr/x86/ogrng-d-avx-lzcnt-asm.asm client-new3c/ogr/x86/ogrng-d-avx-lzcnt-asm.asm
--- client-new3a/ogr/x86/ogrng-d-avx-lzcnt-asm.asm	1970-01-01 01:00:00.000000000 +0100
+++ client-new3c/ogr/x86/ogrng-d-avx-lzcnt-asm.asm	2012-09-10 16:26:18.000000000 +0200
@@ -0,0 +1,478 @@
+%ifdef __OMF__ ; Watcom and Borland compilers/linkers
+	[SECTION _DATA USE32 ALIGN=32 CLASS=DATA]
+	[SECTION _TEXT FLAT USE32 align=32 CLASS=CODE]
+%else
+	[SECTION .data]
+	[SECTION .text]
+%endif
+
+extern newbit_table
+
+; global defines
+	%define OGR_MAXDEPTH	1Dh
+	%define sizeof_level	100h
+	%define sizeof_levels	1D00h
+
+; oState offsets
+	%define P_max		000h
+	%define P_maxdepthm1	008h
+	%define P_half_depth	00Ch
+	%define P_half_depth2	010h
+	%define P_stopdepth	018h
+	%define P_depth		01Ch
+
+; parms
+	%define param_oState	01Ch
+	%define param_pnodes	020h
+	%define param_pchoose	024h
+
+; local vars
+	%define L_max		000h
+	%define L_max_m1	000h ; alias
+;	%define L_maxdepthm1	004h
+;	%define L_half_depth	008h
+;	%define L_half_depth2	00Ch
+;	%define L_stopdepth	010h
+;	%define old_esp		014h
+;	%define oState		018h
+;	%define pnodes		01Ch
+;	%define pchoose		020h
+;	%define nodes		024h
+
+	%define L_maxdepthm1	020h
+	%define L_half_depth	040h
+	%define L_half_depth2	060h
+	%define L_stopdepth	080h
+	%define old_esp		0A0h
+	%define oState		0C0h
+	%define pnodes		0E0h
+	%define pchoose		100h
+	%define nodes		120h
+
+; copy oState values for easier access
+
+	%define sizeof_local	140h
+
+; struct OgrLevel offsets
+	%define list		020h
+	%define dist		060h
+	%define comp		0A0h
+	%define mark		0E0h
+	%define limit		0E4h
+
+
+;----------------;
+;  HEADER MACRO  ;
+;----------------;
+
+%macro _header_ 0
+header:
+	push		ebx
+	push		ecx
+	push		edx
+	push		edi
+	push		esi
+	push		ebp
+	mov		eax, esp
+
+; Create 32 byte aligned stack frame for faster access rate.
+
+	sub		esp, sizeof_local
+	and		esp, 0FFFFFFE0h
+
+; We must copy all function parameters into local stack frame. Because they
+; become unavailable after stack align.
+
+	mov		ebx, [eax + param_oState]
+	mov		ecx, [eax + param_pnodes]
+	mov		edx, [eax + param_pchoose]
+	mov		[esp + old_esp], eax
+	mov		[esp + oState], ebx
+	mov		[esp + pnodes], ecx
+	mov		[esp + pchoose], edx
+
+; Zero ymm registers.
+
+	vzeroall
+
+; Init local node count, and copy oState fields to local frame for easier
+; and faster access.
+
+	mov		ecx, [ecx]
+	mov		[esp + nodes], ecx
+	add		ebx, sizeof_levels
+;	vmovdqa		ymm0, [ebx]
+;	vmovdqa		[esp + L_oState], ymm0
+	mov		edx, [ebx + P_max]
+	mov		[esp + L_max], edx
+	mov		edx, [ebx + P_maxdepthm1]
+	mov		[esp + L_maxdepthm1], edx
+	mov		edx, [ebx + P_half_depth]
+	mov		[esp + L_half_depth], edx
+	mov		edx, [ebx + P_half_depth2]
+	mov		[esp + L_half_depth2], edx
+	mov		edx, [ebx + P_stopdepth]
+	mov		[esp + L_stopdepth], edx
+	mov		ebp, [ebx + P_depth]
+
+; Count initial newbit value.
+
+	xor		eax, eax
+;	mov		ebp, [esp + L_depth]
+	mov		ebx, ebp
+	cmp		ebx, [esp + L_maxdepthm1]
+	setb		al
+	mov		edi, eax
+
+; Make ebp points to current OgrLevel for easier and faster acces.
+
+	shl		ebp, 8 ; depth * sizeof_level
+	mov		eax, [esp + oState]
+	add		ebp, eax
+
+; L_max is not used directly only decremented by 1. Always.
+
+	sub		dword [esp + L_max], 1
+%endmacro
+
+;--------------------;
+;  LEVEL_LOOP MACRO  ;
+;--------------------;
+
+%macro _level_loop_ 0
+align 16
+level_loop:
+
+; Find first blank at WHOLE bitmap comp at once.
+
+	xor		edx, edx
+	mov		ecx, 0FFFFFFFFh
+
+	mov		eax, [ebp + comp + 4]
+	xor		eax, ecx
+	lzcnt		eax, eax
+	jnc		end_lzcnt
+	inc		edx
+
+	mov		eax, [ebp + comp]
+	xor		eax, ecx
+	lzcnt		eax, eax
+	jnc		end_lzcnt
+	inc		edx
+
+	mov		eax, [ebp + comp + 12]
+	xor		eax, ecx
+	lzcnt		eax, eax
+	jnc		end_lzcnt
+	inc		edx
+
+	mov		eax, [ebp + comp + 8]
+	xor		eax, ecx
+	lzcnt		eax, eax
+	jnc		end_lzcnt
+	inc		edx
+
+	mov		eax, [ebp + comp + 20]
+	xor		eax, ecx
+	lzcnt		eax, eax
+	jnc		end_lzcnt
+	inc		edx
+
+;	mov		eax, [ebp + comp + 16]
+;	xor		eax, ecx
+;	lzcnt		eax, eax
+;	jnc		end_lzcnt
+;	inc		edx
+
+;	mov		eax, [ebp + comp + 28]
+;	xor		eax, ecx
+;	lzcnt		eax, eax
+;	jnc		end_lzcnt
+;	inc		edx
+
+;	mov		eax, [ebp + comp + 24]
+;	xor		eax, ecx
+;	lzcnt		eax, eax
+;	jnc		end_lzcnt
+;	inc		edx
+
+align 16
+end_lzcnt:
+	shl		edx, 5
+	add		edx, eax
+	inc		edx
+
+; Count new mark and compare it with limit.
+
+	add		esi, edx
+	cmp		esi, [ebp + limit]
+	ja		level_loop_end
+	mov		[ebp + mark], esi
+
+; ONE PASS shift stage 1
+; Find whole qword shift and single qword internal shift.
+
+	vzeroall
+	mov		ecx, edx
+	mov		eax, edx
+	shr		ecx, 6
+	and		edx, 03Fh
+	movd		xmm7, edx
+	sub		edx, 64
+	neg		edx
+	movd		xmm6, edx
+
+; ONE PASS shift stage 2
+; Fetch whole qword shifted bitmaps and shifted one more copy.
+
+;	vpermilpd	ymm0, ymm1, 0101b	; ymm0:BADC
+;	vextractf128	xmm4, ymm0, 1		; xmm4:BA xmm0:DC
+;	vblendpd	xmm4, xmm4, xmm0, 01b	; ymm4:00BC
+;	vblendpd	ymm0, ymm0, ymm4, 1011b	; ymm0:0ABC
+
+;	vpermilpd	ymm2, ymm3, 0101b	; ymm2:BADC
+;	vextractf128	xmm4, ymm2, 1		; xmm4:BA xmm2:DC
+;	blendpd		xmm4, xmm2, 01b		; ymm4:00BC
+;	blendpd		xmm2, xmm5, 01b		; ymm2:00D0
+;	vinsertf128	ymm2, ymm2, xmm4, 1	; ymm2:BCD0
+
+	test		ecx, ecx
+	jnz		check_shift_1
+	vmovdqa		ymm1, [ebp + comp]
+	vmovdqu		ymm0, [ebp + comp + 08h]
+	vmovdqu		ymm2, [ebp + list - 08h]
+	vmovdqa		ymm3, [ebp + list]
+
+	jmp		bitmap_loaded
+align 16
+check_shift_1:
+	sub		cl, 2
+	jae		check_shift_2
+	vmovdqu		ymm1, [ebp + comp + 08h]
+	vmovdqu		ymm0, [ebp + comp + 10h]
+;	movdqa		xmm0, [ebp + comp + 10h]
+	vmovdqu		ymm2, [ebp + list - 10h]
+;	vinsertf128	ymm2, ymm2, [ebp + list], 1
+	vmovdqu		ymm3, [ebp + list - 08h]
+	jmp		bitmap_loaded
+align 16
+check_shift_2:
+;;	ja		check_shift_3
+	vmovdqu		ymm1, [ebp + comp + 10h]
+;	movdqa		xmm1, [ebp + comp + 10h]
+	vmovdqu		ymm0, [ebp + comp + 18h]
+	vmovdqu		ymm2, [ebp + list - 18h]
+	vmovdqu		ymm3, [ebp + list - 10h]
+;	vinsertf128	ymm3, ymm3, [ebp + list], 1
+	jmp		bitmap_loaded
+;;align 16
+;;check_shift_3:
+
+; Note that +- 20h will be all 0 so not fetch them.
+
+;;	vmovdqu		ymm1, [ebp + comp + 18h]
+;;	vmovdqu		ymm3, [ebp + list - 18h]
+align 16
+bitmap_loaded:
+
+; ONE PASS shift stage 3
+; Shift comp bitmap - we must use xmm since there are no ymm shift
+; command in AVX instruction set.
+
+;	psrlq		xmm0, xmm6 ; lo128
+;	psllq		xmm1, xmm7
+;	vperm2f128	ymm0, ymm0, ymm0, 00100011b
+;	vperm2f128	ymm1, ymm1, ymm1, 00100011b
+;	psrlq		xmm0, xmm6 ; hi128
+;	psllq		xmm1, xmm7
+;	vorpd		ymm0, ymm0, ymm1
+;	vperm2f128	ymm0, ymm0, ymm0, 00100011b
+
+
+	vextractf128	xmm4, ymm0, 1
+	vextractf128	xmm5, ymm1, 1
+	psrlq		xmm0, xmm6
+	psrlq		xmm4, xmm6
+	psllq		xmm1, xmm7
+	psllq		xmm5, xmm7
+	vinsertf128	ymm0, ymm0, xmm4, 1
+	vinsertf128	ymm1, ymm1, xmm5, 1
+	vorpd		ymm0, ymm0, ymm1
+
+	vmovdqa		[ebp + comp], ymm0
+
+; ONE PASS shift stage 4
+; Shift list bitmap and 'or' it with newbit table.
+
+;	psllq		xmm2, xmm6 ; lo128
+;	psrlq		xmm3, xmm7
+;	vperm2f128	ymm2, ymm2, ymm2, 00100011b
+;	vperm2f128	ymm3, ymm3, ymm3, 00100011b
+;	psllq		xmm2, xmm6 ; hi128
+;	psrlq		xmm3, xmm7
+;	vorpd		ymm2, ymm2, ymm3
+;	vperm2f128	ymm2, ymm2, ymm2, 00100011b
+
+
+	vextractf128	xmm4, ymm2, 1
+	vextractf128	xmm5, ymm3, 1
+	psllq		xmm4, xmm6
+	psllq		xmm2, xmm6
+	psrlq		xmm5, xmm7
+	psrlq		xmm3, xmm7
+	vinsertf128	ymm2, ymm2, xmm4, 1
+	vinsertf128	ymm3, ymm3, xmm5, 1
+	vorpd		ymm2, ymm2, ymm3
+
+	test		edi, edi
+	jz		no_newbit
+	shl		eax, 5
+	vorpd		ymm2, ymm2, [eax + newbit_table]
+align 16
+no_newbit:
+	vmovdqa		[ebp + list], ymm2
+
+; Check for exit condition.
+
+	cmp		ebx, [esp + L_maxdepthm1]
+	jz		footer
+
+; Prepare and go to next level.
+
+	vmovdqa		[ebp + sizeof_level + list], ymm2
+	vorpd		ymm3, ymm2, [ebp + dist]
+	vmovdqa		[ebp + sizeof_level + dist], ymm3
+	vorpd		ymm4, ymm0, ymm3
+	vmovdqa		[ebp + sizeof_level + comp], ymm4
+
+; Newbit must be nonzero, so it can be half_depth also...
+
+	mov		edi, [esp + L_half_depth]
+	add		ebp, sizeof_level
+	inc		ebx
+
+
+; Get limit from choose table.
+
+	pextrd		edx, xmm3, 1b
+	mov		eax, edx
+	shr		eax, 16
+	shl		eax, 5
+	add		eax, ebx
+	mov		ecx, [esp + pchoose]
+	movzx		eax, word [ecx + eax * 2]
+
+; Check for "half" operations.
+
+	cmp		eax, edi ; as halfdepth
+	jle		save_limit
+	cmp		ebx, [esp + L_half_depth2]
+	ja		save_limit
+
+; Do "half" operations, temp count is delayed.
+
+	jz		no_fblank
+	xor		edx, 0FFFFFFFFh
+	lzcnt		edx, edx
+	inc		edx
+	add		edx, esi ; + halfdepth mark - see comment below
+	jmp		count_temp
+align 16
+no_fblank:
+; Place oState[halfdepth].mark in edx.
+; There are 2 cases halfdepth = "depth - 1" or "depth - 2"
+; Note that [depth - 1].mark is in esi.
+
+	mov		edx, esi
+	dec		ebx
+	cmp		ebx, edi
+	cmova		edx, [ebp - 2 * sizeof_level + mark]
+	inc		ebx
+;	jmp		count_temp
+align 16
+count_temp:
+	mov		ecx, [esp + L_max_m1]
+	sub		ecx, edx
+	cmp		eax, ecx
+	cmova		eax, ecx
+align 16
+save_limit:
+
+; Save limit and decrease node count
+
+	mov		[ebp + limit], eax
+	sub		dword [esp + nodes], 1
+	ja		level_loop
+	mov		[ebp + mark], esi
+	jmp		footer
+align 16
+level_loop_end:
+%endmacro
+
+;-------------------;
+;  MAIN_LOOP MACRO  ;
+;-------------------;
+
+%macro _main_loop_ 0
+align 16
+main_loop:
+
+; Init local mark
+	mov		esi, [ebp + mark]
+
+; Do level loop
+
+	_level_loop_
+
+; Decrement depth and OgrLevel counter and cleanp newbit.
+
+	dec		ebx
+	sub		ebp, sizeof_level
+	xor		edi, edi
+
+; Check exit condition.
+
+	cmp		ebx, [esp + L_stopdepth]
+	ja		main_loop
+%endmacro
+
+;----------------;
+;  FOOTER MACRO  ;
+;----------------;
+
+%macro _footer_ 0
+align 16
+footer:
+
+; Set *pnodes to node count we check.
+
+	mov		ecx, [esp + nodes]
+	mov		eax, [esp + pnodes]
+	sub		[eax], ecx
+
+; Restore esp and registers and set return value to current depth.
+
+;	mov		eax, [esp + L_depth]
+	mov		eax, ebx
+	mov		esp, [esp + old_esp]
+	pop		ebp
+	pop		esi
+	pop		edi
+	pop		edx
+	pop		ecx
+	pop		ebx
+	ret
+%endmacro
+
+;-----------------;
+;  FUNCTION BODY  ;
+;-----------------;
+
+global		_ogr_cycle_256_d_avx_lzcnt
+global		ogr_cycle_256_d_avx_lzcnt
+_ogr_cycle_256_d_avx_lzcnt:
+ogr_cycle_256_d_avx_lzcnt:
+
+	_header_
+	_main_loop_
+	_footer_
diff -ruN client-new3a/ogr/x86/ogrng-d-avx-lzcnt.cpp client-new3c/ogr/x86/ogrng-d-avx-lzcnt.cpp
--- client-new3a/ogr/x86/ogrng-d-avx-lzcnt.cpp	1970-01-01 01:00:00.000000000 +0100
+++ client-new3c/ogr/x86/ogrng-d-avx-lzcnt.cpp	2012-08-31 20:04:30.000000000 +0200
@@ -0,0 +1,160 @@
+#include "ansi/ogrng-64.h"
+
+#define OGROPT_HAVE_FIND_FIRST_ZERO_BIT_ASM   0 /* 0-2 - 'no'            */
+#define OGROPT_ALTERNATE_CYCLE                1 /* 0/1 - 'yes'           */
+#define OGR_NG_GET_DISPATCH_TABLE_FXN  ogrng_get_dispatch_table_d_avx_lzcnt
+#define OGROPT_SPECIFIC_LEVEL_STRUCT
+#define OGROPT_SPECIFIC_STATE_STRUCT
+
+/*
+ ** Level datas.
+ */
+struct OgrLevel {
+/* 128 byte cache align*/
+   BMAP pad0[OGRNG_BITMAPS_WORDS];
+   BMAP list[OGRNG_BITMAPS_WORDS];
+   BMAP pad1[OGRNG_BITMAPS_WORDS];
+   BMAP dist[OGRNG_BITMAPS_WORDS];
+/* 128 byte cache align*/
+   BMAP pad2[OGRNG_BITMAPS_WORDS];
+   BMAP comp[OGRNG_BITMAPS_WORDS];
+   BMAP pad3[OGRNG_BITMAPS_WORDS];
+   int mark;
+   int limit;
+   int pad4[6];
+};
+
+/*
+ ** Full state.
+ */
+struct OgrState {
+   struct OgrLevel Levels[OGR_MAXDEPTH];
+   int max;                  /* Maximum length of the ruler */
+   int maxdepth;             /* maximum number of marks in ruler */
+   int maxdepthm1;           /* maxdepth-1 */
+   int half_depth;           /* half of maxdepth */
+   int half_depth2;          /* half of maxdepth, adjusted for 2nd mark */
+   int startdepth;           /* Initial depth */
+   int stopdepth;            /* May be lower than startdepth */
+   int depth;                /* Current depth */
+};
+
+BMAP newbit_table[257 * OGRNG_BITMAPS_WORDS] __attribute__ ((aligned (32))) = { 0, 0, 0, 0,
+	0x8000000000000000ll, 0, 0, 0, 0x4000000000000000ll, 0, 0, 0, 0x2000000000000000ll, 0, 0, 0, 0x1000000000000000ll, 0, 0, 0,
+	0x0800000000000000ll, 0, 0, 0, 0x0400000000000000ll, 0, 0, 0, 0x0200000000000000ll, 0, 0, 0, 0x0100000000000000ll, 0, 0, 0,
+	0x0080000000000000ll, 0, 0, 0, 0x0040000000000000ll, 0, 0, 0, 0x0020000000000000ll, 0, 0, 0, 0x0010000000000000ll, 0, 0, 0,
+	0x0008000000000000ll, 0, 0, 0, 0x0004000000000000ll, 0, 0, 0, 0x0002000000000000ll, 0, 0, 0, 0x0001000000000000ll, 0, 0, 0,
+	0x0000800000000000ll, 0, 0, 0, 0x0000400000000000ll, 0, 0, 0, 0x0000200000000000ll, 0, 0, 0, 0x0000100000000000ll, 0, 0, 0,
+	0x0000080000000000ll, 0, 0, 0, 0x0000040000000000ll, 0, 0, 0, 0x0000020000000000ll, 0, 0, 0, 0x0000010000000000ll, 0, 0, 0,
+	0x0000008000000000ll, 0, 0, 0, 0x0000004000000000ll, 0, 0, 0, 0x0000002000000000ll, 0, 0, 0, 0x0000001000000000ll, 0, 0, 0,
+	0x0000000800000000ll, 0, 0, 0, 0x0000000400000000ll, 0, 0, 0, 0x0000000200000000ll, 0, 0, 0, 0x0000000100000000ll, 0, 0, 0,
+	0x0000000080000000ll, 0, 0, 0, 0x0000000040000000ll, 0, 0, 0, 0x0000000020000000ll, 0, 0, 0, 0x0000000010000000ll, 0, 0, 0,
+	0x0000000008000000ll, 0, 0, 0, 0x0000000004000000ll, 0, 0, 0, 0x0000000002000000ll, 0, 0, 0, 0x0000000001000000ll, 0, 0, 0,
+	0x0000000000800000ll, 0, 0, 0, 0x0000000000400000ll, 0, 0, 0, 0x0000000000200000ll, 0, 0, 0, 0x0000000000100000ll, 0, 0, 0,
+	0x0000000000080000ll, 0, 0, 0, 0x0000000000040000ll, 0, 0, 0, 0x0000000000020000ll, 0, 0, 0, 0x0000000000010000ll, 0, 0, 0,
+	0x0000000000008000ll, 0, 0, 0, 0x0000000000004000ll, 0, 0, 0, 0x0000000000002000ll, 0, 0, 0, 0x0000000000001000ll, 0, 0, 0,
+	0x0000000000000800ll, 0, 0, 0, 0x0000000000000400ll, 0, 0, 0, 0x0000000000000200ll, 0, 0, 0, 0x0000000000000100ll, 0, 0, 0,
+	0x0000000000000080ll, 0, 0, 0, 0x0000000000000040ll, 0, 0, 0, 0x0000000000000020ll, 0, 0, 0, 0x0000000000000010ll, 0, 0, 0,
+	0x0000000000000008ll, 0, 0, 0, 0x0000000000000004ll, 0, 0, 0, 0x0000000000000002ll, 0, 0, 0, 0x0000000000000001ll, 0, 0, 0,
+
+	0, 0x8000000000000000ll, 0, 0, 0, 0x4000000000000000ll, 0, 0, 0, 0x2000000000000000ll, 0, 0, 0, 0x1000000000000000ll, 0, 0,
+	0, 0x0800000000000000ll, 0, 0, 0, 0x0400000000000000ll, 0, 0, 0, 0x0200000000000000ll, 0, 0, 0, 0x0100000000000000ll, 0, 0,
+	0, 0x0080000000000000ll, 0, 0, 0, 0x0040000000000000ll, 0, 0, 0, 0x0020000000000000ll, 0, 0, 0, 0x0010000000000000ll, 0, 0,
+	0, 0x0008000000000000ll, 0, 0, 0, 0x0004000000000000ll, 0, 0, 0, 0x0002000000000000ll, 0, 0, 0, 0x0001000000000000ll, 0, 0,
+	0, 0x0000800000000000ll, 0, 0, 0, 0x0000400000000000ll, 0, 0, 0, 0x0000200000000000ll, 0, 0, 0, 0x0000100000000000ll, 0, 0,
+	0, 0x0000080000000000ll, 0, 0, 0, 0x0000040000000000ll, 0, 0, 0, 0x0000020000000000ll, 0, 0, 0, 0x0000010000000000ll, 0, 0,
+	0, 0x0000008000000000ll, 0, 0, 0, 0x0000004000000000ll, 0, 0, 0, 0x0000002000000000ll, 0, 0, 0, 0x0000001000000000ll, 0, 0,
+	0, 0x0000000800000000ll, 0, 0, 0, 0x0000000400000000ll, 0, 0, 0, 0x0000000200000000ll, 0, 0, 0, 0x0000000100000000ll, 0, 0,
+	0, 0x0000000080000000ll, 0, 0, 0, 0x0000000040000000ll, 0, 0, 0, 0x0000000020000000ll, 0, 0, 0, 0x0000000010000000ll, 0, 0,
+	0, 0x0000000008000000ll, 0, 0, 0, 0x0000000004000000ll, 0, 0, 0, 0x0000000002000000ll, 0, 0, 0, 0x0000000001000000ll, 0, 0,
+	0, 0x0000000000800000ll, 0, 0, 0, 0x0000000000400000ll, 0, 0, 0, 0x0000000000200000ll, 0, 0, 0, 0x0000000000100000ll, 0, 0,
+	0, 0x0000000000080000ll, 0, 0, 0, 0x0000000000040000ll, 0, 0, 0, 0x0000000000020000ll, 0, 0, 0, 0x0000000000010000ll, 0, 0,
+	0, 0x0000000000008000ll, 0, 0, 0, 0x0000000000004000ll, 0, 0, 0, 0x0000000000002000ll, 0, 0, 0, 0x0000000000001000ll, 0, 0,
+	0, 0x0000000000000800ll, 0, 0, 0, 0x0000000000000400ll, 0, 0, 0, 0x0000000000000200ll, 0, 0, 0, 0x0000000000000100ll, 0, 0,
+	0, 0x0000000000000080ll, 0, 0, 0, 0x0000000000000040ll, 0, 0, 0, 0x0000000000000020ll, 0, 0, 0, 0x0000000000000010ll, 0, 0,
+	0, 0x0000000000000008ll, 0, 0, 0, 0x0000000000000004ll, 0, 0, 0, 0x0000000000000002ll, 0, 0, 0, 0x0000000000000001ll, 0, 0,
+
+	0, 0, 0x8000000000000000ll, 0, 0, 0, 0x4000000000000000ll, 0, 0, 0, 0x2000000000000000ll, 0, 0, 0, 0x1000000000000000ll, 0,
+	0, 0, 0x0800000000000000ll, 0, 0, 0, 0x0400000000000000ll, 0, 0, 0, 0x0200000000000000ll, 0, 0, 0, 0x0100000000000000ll, 0,
+	0, 0, 0x0080000000000000ll, 0, 0, 0, 0x0040000000000000ll, 0, 0, 0, 0x0020000000000000ll, 0, 0, 0, 0x0010000000000000ll, 0,
+	0, 0, 0x0008000000000000ll, 0, 0, 0, 0x0004000000000000ll, 0, 0, 0, 0x0002000000000000ll, 0, 0, 0, 0x0001000000000000ll, 0,
+	0, 0, 0x0000800000000000ll, 0, 0, 0, 0x0000400000000000ll, 0, 0, 0, 0x0000200000000000ll, 0, 0, 0, 0x0000100000000000ll, 0,
+	0, 0, 0x0000080000000000ll, 0, 0, 0, 0x0000040000000000ll, 0, 0, 0, 0x0000020000000000ll, 0, 0, 0, 0x0000010000000000ll, 0,
+	0, 0, 0x0000008000000000ll, 0, 0, 0, 0x0000004000000000ll, 0, 0, 0, 0x0000002000000000ll, 0, 0, 0, 0x0000001000000000ll, 0,
+	0, 0, 0x0000000800000000ll, 0, 0, 0, 0x0000000400000000ll, 0, 0, 0, 0x0000000200000000ll, 0, 0, 0, 0x0000000100000000ll, 0,
+	0, 0, 0x0000000080000000ll, 0, 0, 0, 0x0000000040000000ll, 0, 0, 0, 0x0000000020000000ll, 0, 0, 0, 0x0000000010000000ll, 0,
+	0, 0, 0x0000000008000000ll, 0, 0, 0, 0x0000000004000000ll, 0, 0, 0, 0x0000000002000000ll, 0, 0, 0, 0x0000000001000000ll, 0,
+	0, 0, 0x0000000000800000ll, 0, 0, 0, 0x0000000000400000ll, 0, 0, 0, 0x0000000000200000ll, 0, 0, 0, 0x0000000000100000ll, 0,
+	0, 0, 0x0000000000080000ll, 0, 0, 0, 0x0000000000040000ll, 0, 0, 0, 0x0000000000020000ll, 0, 0, 0, 0x0000000000010000ll, 0,
+	0, 0, 0x0000000000008000ll, 0, 0, 0, 0x0000000000004000ll, 0, 0, 0, 0x0000000000002000ll, 0, 0, 0, 0x0000000000001000ll, 0,
+	0, 0, 0x0000000000000800ll, 0, 0, 0, 0x0000000000000400ll, 0, 0, 0, 0x0000000000000200ll, 0, 0, 0, 0x0000000000000100ll, 0,
+	0, 0, 0x0000000000000080ll, 0, 0, 0, 0x0000000000000040ll, 0, 0, 0, 0x0000000000000020ll, 0, 0, 0, 0x0000000000000010ll, 0,
+	0, 0, 0x0000000000000008ll, 0, 0, 0, 0x0000000000000004ll, 0, 0, 0, 0x0000000000000002ll, 0, 0, 0, 0x0000000000000001ll, 0,
+
+	0, 0, 0, 0x8000000000000000ll, 0, 0, 0, 0x4000000000000000ll, 0, 0, 0, 0x2000000000000000ll, 0, 0, 0, 0x1000000000000000ll,
+	0, 0, 0, 0x0800000000000000ll, 0, 0, 0, 0x0400000000000000ll, 0, 0, 0, 0x0200000000000000ll, 0, 0, 0, 0x0100000000000000ll,
+	0, 0, 0, 0x0080000000000000ll, 0, 0, 0, 0x0040000000000000ll, 0, 0, 0, 0x0020000000000000ll, 0, 0, 0, 0x0010000000000000ll,
+	0, 0, 0, 0x0008000000000000ll, 0, 0, 0, 0x0004000000000000ll, 0, 0, 0, 0x0002000000000000ll, 0, 0, 0, 0x0001000000000000ll,
+	0, 0, 0, 0x0000800000000000ll, 0, 0, 0, 0x0000400000000000ll, 0, 0, 0, 0x0000200000000000ll, 0, 0, 0, 0x0000100000000000ll,
+	0, 0, 0, 0x0000080000000000ll, 0, 0, 0, 0x0000040000000000ll, 0, 0, 0, 0x0000020000000000ll, 0, 0, 0, 0x0000010000000000ll,
+	0, 0, 0, 0x0000008000000000ll, 0, 0, 0, 0x0000004000000000ll, 0, 0, 0, 0x0000002000000000ll, 0, 0, 0, 0x0000001000000000ll,
+	0, 0, 0, 0x0000000800000000ll, 0, 0, 0, 0x0000000400000000ll, 0, 0, 0, 0x0000000200000000ll, 0, 0, 0, 0x0000000100000000ll,
+	0, 0, 0, 0x0000000080000000ll, 0, 0, 0, 0x0000000040000000ll, 0, 0, 0, 0x0000000020000000ll, 0, 0, 0, 0x0000000010000000ll,
+	0, 0, 0, 0x0000000008000000ll, 0, 0, 0, 0x0000000004000000ll, 0, 0, 0, 0x0000000002000000ll, 0, 0, 0, 0x0000000001000000ll,
+	0, 0, 0, 0x0000000000800000ll, 0, 0, 0, 0x0000000000400000ll, 0, 0, 0, 0x0000000000200000ll, 0, 0, 0, 0x0000000000100000ll,
+	0, 0, 0, 0x0000000000080000ll, 0, 0, 0, 0x0000000000040000ll, 0, 0, 0, 0x0000000000020000ll, 0, 0, 0, 0x0000000000010000ll,
+	0, 0, 0, 0x0000000000008000ll, 0, 0, 0, 0x0000000000004000ll, 0, 0, 0, 0x0000000000002000ll, 0, 0, 0, 0x0000000000001000ll,
+	0, 0, 0, 0x0000000000000800ll, 0, 0, 0, 0x0000000000000400ll, 0, 0, 0, 0x0000000000000200ll, 0, 0, 0, 0x0000000000000100ll,
+	0, 0, 0, 0x0000000000000080ll, 0, 0, 0, 0x0000000000000040ll, 0, 0, 0, 0x0000000000000020ll, 0, 0, 0, 0x0000000000000010ll,
+	0, 0, 0, 0x0000000000000008ll, 0, 0, 0, 0x0000000000000004ll, 0, 0, 0, 0x0000000000000002ll, 0, 0, 0, 0x0000000000000001ll,
+};
+
+#include "ansi/ogrng_codebase.cpp"
+
+#include "ccoreio.h"       /* CDECL */
+#include <stddef.h>        /* offsetof */
+#include <stdio.h>        /* offsetof */
+#include <endian.h>        /* offsetof */
+#include <string.h>        /* offsetof */
+#include <stdlib.h>        /* offsetof */
+
+extern "C" int CDECL ogr_cycle_256_d_avx_lzcnt(struct OgrState *oState, int *pnodes, const u16* pchoose);
+
+
+
+
+static int ogr_cycle_256(struct OgrState *oState, int *pnodes, const u16* pchoose)
+{
+
+    struct OgrState loState __attribute__ ((aligned (32)));
+    int ret;
+
+    /* Check that size of cruncher thread work area is correct */
+
+    STATIC_ASSERT(sizeof(struct OgrState) <= OGRNG_PROBLEM_SIZE);
+
+    /* Check structures layout and alignment to match assembly */
+
+    STATIC_ASSERT(offsetof(struct OgrState, max)         == 0x1D00);
+    STATIC_ASSERT(offsetof(struct OgrState, maxdepthm1)  == 0x1D08);
+    STATIC_ASSERT(offsetof(struct OgrState, half_depth)  == 0x1D0C);
+    STATIC_ASSERT(offsetof(struct OgrState, half_depth2) == 0x1D10);
+    STATIC_ASSERT(offsetof(struct OgrState, stopdepth)   == 0x1D18);
+    STATIC_ASSERT(offsetof(struct OgrState, depth)       == 0x1D1C);
+    STATIC_ASSERT(offsetof(struct OgrState, Levels)      == 0x0000);
+
+    STATIC_ASSERT(sizeof(struct OgrLevel) == 256);
+    STATIC_ASSERT(sizeof(oState->Levels)  == 256 * OGR_MAXDEPTH);
+
+    STATIC_ASSERT(offsetof(struct OgrLevel, list)  == 0x20);
+    STATIC_ASSERT(offsetof(struct OgrLevel, dist)  == 0x60);
+    STATIC_ASSERT(offsetof(struct OgrLevel, comp)  == 0xA0);
+    STATIC_ASSERT(offsetof(struct OgrLevel, mark)  == 0xE0);
+    STATIC_ASSERT(offsetof(struct OgrLevel, limit) == 0xE4);
+
+    memcpy(&loState, oState, sizeof(loState));
+    ret = ogr_cycle_256_d_avx_lzcnt(&loState, pnodes, pchoose);
+    memcpy(oState, &loState, sizeof(loState));
+
+    return ret;
+}

--nextPart149716847.PGV5MnnxLd
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

_______________________________________________
Hardware mailing list
Hardware-Ra3b/QYEcJ3d140v2zMXi0fjHoOT/h/[email protected]
http://lists.distributed.net/mailman/listinfo/hardware

--nextPart149716847.PGV5MnnxLd--