
рд╕реНрдЯреИрдВрд╕рд┐рд▓ рдмрдлрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдЙрди рдЬрдЧрд╣реЛрдВ рдкрд░ рдкреНрд░рддрд┐рдмрд┐рдВрдмреЛрдВ рдХреЛ рдореБрдЦреМрдЯрд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬрд╣рд╛рдВ рд╡реЗ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдирд╣реАрдВ рд╣реИрдВред рд╕реНрдЯреИрдВрд╕рд┐рд▓ рддрдХрдиреАрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдУрдкрдирдЬреАрдПрд▓ рдФрд░ рдбрд╛рдпрд░реЗрдХреНрдЯрдПрдХреНрд╕ рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рдПрдХ рд╕реНрдЯреИрдВрд╕рд┐рд▓ рдкрд░реАрдХреНрд╖рдг рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдЙрди рдЬрдЧрд╣реЛрдВ рдкрд░ рдЬрд╣рд╛рдВ рдХреЛрдИ рдЫрд╡рд┐ рдирд╣реАрдВ рд╣реИ, рдкрд┐рдХреНрд╕реЗрд▓ shader рдкреНрд░рджрд╛рди рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рд╣рдо рдЕрдирд╛рд╡рд╢реНрдпрдХ рдХрд╛рдо рдХреЛ рджрдмрд╛ рджреЗрддреЗ рд╣реИрдВред
рд╕реНрдЯреИрдВрд╕рд┐рд▓ рдХреЛ рдЧрд╣рд░рд╛рдИ рдХреЗ рд╕рд╛рде рдПрдХ рдмрдлрд░ рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдбреА 3 рдбреАрдПрдлрдПрдордЯреА_ рдбреА 24 рдПрд╕ 8 рдкреНрд░рд╛рд░реВрдк рдореЗрдВ, 24 рдмрд┐рдЯ рдЧрд╣рд░рд╛рдИ рдмрд┐рдЯ рдФрд░ 8 рдмрд┐рдЯ рд╕реНрдЯреЗрдВрд╕рд┐рд▓ рд╣реИрдВред рд╕рд╛рджрдЧреА рдХреЗ рд▓рд┐рдП, рд╣рдо рдЖрдЧреЗ рдорд╛рдиреЗрдВрдЧреЗ рдХрд┐ рд╕реНрдЯреИрдВрд╕рд┐рд▓ рдЕрдВрддрд┐рдо рдмрд┐рдЯ рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рд╣реИред рдпрджрд┐ рдпрд╣ рдмрд┐рдЯ = 1 рд╣реИ, рддреЛ рдкрд┐рдХреНрд╕реЗрд▓ рд╕рдХреНрд░рд┐рдп рд╣реИред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рд╕рд░рд▓реАрдХреГрдд рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХрджрдо рдкреНрд░рд╕реНрддреБрдд рдХрд░рддрд╛ рд╣реИ:
- рд╢реВрдиреНрдп (рдЬреАрд░реЛ рд╕реЗ рднрд░реЗрдВ) рд╕реНрдЯреЗрдВрд╕рд┐рд▓ рдмрдлрд░ред
- рд╣рдо рд╕реНрдЯреИрдВрд╕рд┐рд▓ рдмрдлрд░ рдореЗрдВ рдПрдХ рд╡рд┐рдорд╛рди рдХреЛ рд░рд┐рдХреЙрд░реНрдб рдХрд░рдирд╛ рдФрд░ рдЖрдХрд░реНрд╖рд┐рдд рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ, рдЬрд┐рд╕рдХреЗ рд╕рд╛рдкреЗрдХреНрд╖ рд╣рдо рдкреНрд░рддрд┐рдмрд┐рдВрдм рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВрдЧреЗред рдЬрд╣рд╛рдВ рдПрдХ рджрд░реНрдкрдг рд╣реИ, рд╡рд╣рд╛рдВ рдЗрдХрд╛рдЗрдпрд╛рдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдХреА рдЬрд╛рдПрдВрдЧреА, рдФрд░ рдЬрд╣рд╛рдВ рдХреЛрдИ рджрд░реНрдкрдг рдирд╣реАрдВ рд╣реИ, рд╢реВрдиреНрдпред
- рд╣рдо рдПрдХ рдЕрд▓рдЧ рдореИрдЯреНрд░рд┐рдХреНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╡рд┐рдорд╛рди рдХреЗ рд╕рд╛рдкреЗрдХреНрд╖ рд╕рднреА рдЬреНрдпрд╛рдорд┐рддрд┐ рдХреЛ рджрд░реНрд╢рд╛рддреЗ рд╣реИрдВ, рдФрд░ рдлрд┐рд░ рдПрдХ рд╕реНрдЯреИрдВрд╕рд┐рд▓ рдкрд░реАрдХреНрд╖рдг рдЪрд▓рд╛рдиреЗ рдХреЗ рд╕рд╛рде-рд╕рд╛рде рдПрдХ рдкреНрд░рддрд┐рдмрд┐рдВрдм рдЦреАрдВрдЪрддреЗ рд╣реИрдВред
рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдЬрд╣рд╛рдВ рджрд░реНрдкрдг рдЫрд╡рд┐ рдореЗрдВ рдерд╛, рдкреНрд░рддрд┐рдмрд┐рдВрдм рджрд┐рдЦрд╛рдИ рджреЗрдЧрд╛ред рдФрд░ рдЬрд╣рд╛рдВ рдХреЛрдИ рдирд╣реАрдВ рд╣реИ, рд╡рд╣рд╛рдВ рдХреБрдЫ рднреА рдирд╣реАрдВ рдмрджрд▓реЗрдЧрд╛ред
CUDA рд╕реЙрдлреНрдЯрд╡реЗрдпрд░ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди
CUDA, рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, рдХреЛрдИ рд╕реНрдЯреЗрдВрд╕рд┐рд▓ рдкрд░реАрдХреНрд╖рдг рддрдВрддреНрд░ рдирд╣реАрдВ рд╣реИред рдпрд╣ рдПрдХ рдмрд╣реБрдд рд╣реА рдЙрдкрдпреЛрдЧреА рдЯреНрд░рд┐рдХ рд╣реИ рдФрд░ рдореИрдВ рд╕рдордЭрд╛рддрд╛ рд╣реВрдВ рдХрд┐ рдЕрдЧрд▓реЗ рд▓реЗрдЦ рдореЗрдВ рдЗрд╕ рд╕реАрдорд╛ рдХреЗ рдЖрд╕рдкрд╛рд╕ рдХреИрд╕реЗ рдЬрд╛рдирд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЕрдм рд╣рдо рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╡рд┐рд╡рд░рдгреЛрдВ рдХреЛ рджреЗрдЦреЗрдВрдЧреЗред
рддреЛ, рд╣рдо рд╕реНрдЯреИрдВрд╕рд┐рд▓ рдмрдлрд░ рдХреЛ (N / 32) * sizeof (int) рдмрд╛рдЗрдЯреНрд╕ рдХреЗ рдЖрдХрд╛рд░ рд╕реЗ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВред рдФрд░ рдЗрд╕рдХреА рдмрдирд╛рд╡рдЯ рдХреЛ рдмрд╛рдВрдз рджреЗрдВред
cudaMalloc((void**)&m_stencilBuffer, N*sizeof(int)/32); cudaBindTexture(0, stencil_tex, m_stencilBuffer, N*sizeof(int)/32); - (.h ) : Texture<int, 1, cudaReadModeElementType> stencil_tex; , : static __device__ int g_stencilMask[32] = { 0x00000001, 0x00000002, 0x00000004, 0x00000008, 0x00000010, 0x00000020, 0x00000040, 0x00000080, 0x00000100, 0x00000200, 0x00000400, 0x00000800, 0x00001000, 0x00002000, 0x00004000, 0x00008000, 0x00010000, 0x00020000, 0x00040000, 0x00080000, 0x00100000, 0x00200000, 0x00400000, 0x00800000, 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, 0x20000000, 0x40000000, 0x80000000 };
рдЙрди рдЧреБрдард▓реА рдХреЗ рд▓рд┐рдП рдЬреЛ рдХреЗрд╡рд▓ рд╕реНрдЯреИрдВрд╕рд┐рд▓ рдмрдлрд░ рдХреЛ рдкрдврд╝рддреЗ рд╣реИрдВ, рдХрд░реНрдиреЗрд▓ рдХреА рд╢реБрд░реБрдЖрдд рдореЗрдВ рдореИрдХреНрд░реЛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рдХрд░рддреЗ рд╣реИрдВ:
__global__ void my_kernel(тАж) { uint tid = blockDim.x * blockIdx.x + threadIdx.x; STENCIL_TEST(tid);
рд╡реНрдпрд╡рд╣рд╛рд░ рдореЗрдВ (GTX560), рдЗрд╕ рддрд░рд╣ рдХреЗ рд╕реНрдЯреИрдВрд╕рд┐рд▓ рдкрд░реАрдХреНрд╖рдг рдПрдХ рд╕рд╛рдзрд╛рд░рдг рдЬрд╛рдВрдЪ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рд▓рдЧрднрдЧ 20-25% рддреЗрдЬ рд╣реИ, рдкреНрд░рдХрд╛рд░ рдХреА рдЬрд╛рдВрдЪ:
uint activeFlag = a_flags[tid]; if(activeFlag==0) return;
рд╣рд╛рд▓рд╛рдВрдХрд┐, рд╕реНрдореГрддрд┐ рдмрдЪрдд рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрддреЗ рд╣реБрдП, рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рд▓рд╛рдн рд╣реЛрддрд╛ рд╣реИред рдпрд╣ рднреА рдзреНрдпрд╛рди рджрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП рдХрд┐ рдХрдо рдЪреМрдбрд╝реА рдмрд╕ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП GTS450) рдХреЗ рд╕рд╛рде рд╡реАрдбрд┐рдпреЛ рдХрд╛рд░реНрдб рдкрд░, рддреНрд╡рд░рдг рдЕрдзрд┐рдХ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реЛ рд╕рдХрддрд╛ рд╣реИред
рддреЛ, рдпрд╣ рд╕реНрдЯреЗрдВрд╕рд┐рд▓ рдмрдлрд░ рдХреЗ рд▓рд┐рдП рдХреЗрд╡рд▓ рд▓реЗрдЦрди рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд░рд╣рддрд╛ рд╣реИред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╣рдо рдЪреБрдкрдХреЗ рдмрдлрд░ рд╕реЗ рд╕рдХреНрд░рд┐рдпрд╡рд░реНрдк рдЪрд░ рдореЗрдВ рддрд╛рдирд╛ рдореЗрдВ рд╕рдм рдХреБрдЫ рдХреЗ рд▓рд┐рдП рдореВрд▓реНрдп рдкрдврд╝рддреЗ рд╣реИрдВ; рдлрд┐рд░ рдкреНрд░рддреНрдпреЗрдХ рдереНрд░реЗрдб рддрд╛рд░реНрдХрд┐рдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЗрд╕ рдЪрд░ рд╕реЗ рдЕрдкрдирд╛ рдмрд┐рдЯ рдкреНрд░рд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЗрд╕реЗ рд╕рдХреНрд░рд┐рдп рдЪрд░ рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рддрд╛ рд╣реИред рдХрд░реНрдиреЗрд▓ рдХреЗ рдЕрдВрдд рдореЗрдВ, рд╣рдо рджрд┐рдП рдЧрдП рддрд╛рдирд╛ рдХреЗ рдореВрд▓реНрдп рдХреЗ рд▓рд┐рдП рд╕рднреА рд╕рдХреНрд░рд┐рдп рдЪрд░ рд╕реЗ рдПрдХ 32-рдмрд┐рдЯ uint рдореЗрдВ рд╡рд╛рдкрд╕ рдЗрдХрдЯреНрдард╛ рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рд╢реВрдиреНрдп рддрд╛рдирд╛ рдзрд╛рдЧрд╛ рдкрд░рд┐рдгрд╛рдо рдХреЛ рд╕реНрдореГрддрд┐ рдореЗрдВ рд╡рд╛рдкрд╕ рд▓рд┐рдЦ рджреЗрдЧрд╛ред
рдпрджрд┐ рдзрд╛рдЧрд╛ рдирд┐рд╖реНрдХреНрд░рд┐рдп рд╣реИ, рддреЛ рдпрд╣ рддреБрд░рдВрдд рдХрд░реНрдиреЗрд▓ рд╕реНрдХреЗрдЯ рдореЗрдВ рдЬрд╛рдПрдЧрд╛ред рдпрджрд┐ рдХрд┐рд╕реА рдХрд╛рд░рдг рд╕реЗ рдЖрдк рдЕрдкрдиреЗ рдХреЛрдб рдХреЗ рдЕрдВрджрд░ рдпрд╣ рддрдп рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рдпрд╣ рдзрд╛рдЧрд╛ рдирд┐рд╖реНрдХреНрд░рд┐рдп рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП, рддреЛ рдпрд╣ рдХрд░реЗрдВ:
if(want to kill thread) { active = 0; goto WRITE_BACK_STENCIL_DATA; }
рдЙрджрд╛рд╣рд░рдг рдЬрд╛рдирдмреВрдЭрдХрд░ рд▓реЗрдмрд▓ рдФрд░ рдЧреЛрдЯреЛ рдСрдкрд░реЗрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред рд╣рд╛рд▓рд╛рдВрдХрд┐ рдпрд╣ рдПрдХ рдЦрд░рд╛рдм рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рд╢реИрд▓реА рд╣реИ, рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ рдпрд╣ рдЖрдкрдХреЗ рдХреЛрдб рдореЗрдВ рд╕реБрд░рдХреНрд╖рд╛ рдЬреЛрдбрд╝рддрд╛ рд╣реИред рддрдереНрдп рдпрд╣ рд╣реИ рдХрд┐ рдЖрдкрдХреЛ WriteStencilBit рдлрд╝рдВрдХреНрд╢рди рдХреЛрдб рддрдХ рдкрд╣реБрдВрдЪрдиреЗ рдХреА рдЧрд╛рд░рдВрдЯреА рд╣реИред рдпрджрд┐ рдХрд┐рд╕реА рдХрд╛рд░рдг рд╕реЗ рдЖрдк рдЕрдкрдиреЗ рдХреЛрдб рдХреЗ рдЕрдВрджрд░ рд░рд┐рдЯрд░реНрди рдмрдирд╛рдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╕рдм рдХреБрдЫ рдЯреВрдЯ рдЬрд╛рдПрдЧрд╛ (рдереЛрдбрд╝рд╛ рдмрд╛рдж рдореЗрдВ рд╣рдо рдЪрд░реНрдЪрд╛ рдХрд░реЗрдВрдЧреЗ рдХрд┐ рдХреНрдпреЛрдВ)ред рдЗрд╕рдХреЗ рдмрдЬрд╛рдп, рд░рд┐рдЯрд░реНрди рдХреЛ рдЧреЛрдЯреЛ WRITE_BACK_STENCIL_DATA рдкрд░ рд╕реЗрдЯ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП рддрд╛рдХрд┐ рдмрд╛рд╣рд░ рдирд┐рдХрд▓рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рддрд╛рдирд╛-рд╕реЗ рд╕рднреА рдзрд╛рд░рд╛рдПрдВ рдбреЗрдЯрд╛ рдПрдХрддреНрд░ рдХрд░ рд╕рдХреЗрдВ, рдФрд░ рдПрдХ рд╢реВрдиреНрдп рд╕реНрдЯреНрд░реАрдо (рддрд╛рдирд╛ рдХреЗ рдЕрдВрджрд░ рд╢реВрдиреНрдп) рдЙрдиреНрд╣реЗрдВ рд╕реНрдЯреИрдлрд╝рд░реНрдб рдмрдлрд░ рдкрд░ рд▓рд┐рдЦрддрд╛ рд╣реИред рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, WriteStencilBit рдлрд╝рдВрдХреНрд╢рди рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:
__device__ void WriteStencilBit(int tid, uint* a_stencilBuffer, uint value) { uint stencilMask = __ballot(value); if((tid & 0x1f) == 0)
__Ballot () рдлрд╝рдВрдХреНрд╢рди uint рджреЗрддрд╛ рд╣реИ, рдЬрд╣рд╛рдВ рдкреНрд░рддреНрдпреЗрдХ ith рдмрд┐рдЯ 1 рд╣реИ рдпрджрд┐ рдФрд░ рдХреЗрд╡рд▓ рдпрджрд┐ рдЗрд╕рдХреЗ рддрд░реНрдХ рдореЗрдВ рдХреНрдпрд╛ рд╣реИ рддреЛ рд╢реВрдиреНрдп рдирд╣реАрдВ рд╣реИред рдпрд╣реА рд╣реИ, рдпрд╣ рд╡рд╣реА рдХрд░рддрд╛ рд╣реИ рдЬреЛ рдЗрд╕реЗ рд╡рд╣рд╛рдВ рдХреА рдЬрд░реВрд░рдд рд╣реИ, рдЭрдВрдбреЗ рдХреЛ рд╡рд╛рдкрд╕ рддрд╛рдирд╛ рдХреЗ рдЕрдВрджрд░ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдзрд╛рдЧреЗ рд╕реЗ рдЙрдВрдЯ рдореЗрдВ рд╕рд┐рд▓рд╛рдИ рдХрд░рдирд╛ред
__Ballot () рдлрд╝рдВрдХреНрд╢рди рддрдерд╛рдХрдерд┐рдд "рддрд╛рдирд╛ рд╡реЛрдЯ рдХрд╛рд░реНрдпреЛрдВ" рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рд╣реИ рдФрд░ рдмрд╣реБрдд рдЬрд▓реНрджреА рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, рдпрд╣ рдХреЗрд╡рд▓ рдЧрдгрдирд╛ рдХреНрд╖рдорддрд╛ 2.0 рдХреЗ рд▓рд┐рдП рдЙрдкрд▓рдмреНрдз рд╣реИ, рдпрд╛рдиреА рдлрд░реНрдореА рд╡рд╛рд╕реНрддреБрдХрд▓рд╛ рдХреЗ рд╕рд╛рде рд╡реАрдбрд┐рдпреЛ рдХрд╛рд░реНрдбред рдЗрд╕рдХреЗ рд╕рдВрдЪрд╛рд▓рди рдкрд░ рдПрдХ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдиреЛрдЯ, рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЛрдб рдЧрд▓рдд рд╣реЛрдЧрд╛:
__device__ void WriteWrongStencilBit(int tid, uint* a_stencilBuffer, uint value) { if((tid & 0x1f) == 0)
рддрдереНрдп рдпрд╣ рд╣реИ рдХрд┐ __ballot () рд╣рдореЗрд╢рд╛ рдЙрди рдмрд┐рдЯреНрд╕ рдкрд░ 0 рд▓рдЧрд╛рдПрдЧрд╛ рдЬрд┐рдирдХреА рдзрд╛рд░рд╛рдПрдВ рд╡рд░реНрддрдорд╛рди рдореЗрдВ рдирдХрд╛рдмрдкреЛрд╢ рд╣реИрдВред рдФрд░ рдиреЙрди-рдЬрд╝реАрд░реЛ (1..31) рдХреЗ рдЕрдВрджрд░ рдПрдХ рдирдВрдмрд░ рдХреЗ рд╕рд╛рде рд╕рднреА рд╕реНрдЯреНрд░реАрдо рдирдХрд╛рдмрдкреЛрд╢ рд╣реЛрдВрдЧреЗ рдФрд░ рдЕрдЧрд░ рд╕реНрдЯреЗрдЯрдореЗрдВрдЯ рдХреЗ рдЕрдВрджрд░ рдирд╣реАрдВ рдкрд╣реБрдВрдЪреЗрдВрдЧреЗ, рдЗрд╕рд▓рд┐рдП рдЗрд╕ рддрд░рд╣ рдХреЗ рдХреЛрдб рдХреЗ рд▓рд┐рдП __ballot () рдлрд╝рдВрдХреНрд╢рди рдХреЗ 1..31 рдмрд┐рдЯреНрд╕ рд╣рдореЗрд╢рд╛ рд╢реВрдиреНрдп рд╣реЛрдВрдЧреЗред рдпрд╣рд╛рдБ рд╕реЗ рд╕рддреНрдп рдПрдХ рджрд┐рд▓рдЪрд╕реНрдк рдирд┐рд╖реНрдХрд░реНрд╖ рдХрд╛ рдЕрдиреБрд╕рд░рдг рдХрд░рддрд╛ рд╣реИред рдпрджрд┐ рдЖрдкрдХреЛ рдлрд░реНрдореА рд╡рд╛рд╕реНрддреБрдХрд▓рд╛ рдХреЗ рд╕рд╛рде рд╡реАрдбрд┐рдпреЛ рдХрд╛рд░реНрдб рдХреЗ рд▓рд┐рдП рд▓рд┐рдЦрдиреЗ рдХреА рдЧрд╛рд░рдВрдЯреА рджреА рдЬрд╛рддреА рд╣реИ, рддреЛ рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдЧреБрдард▓реА рдХреЗ рд▓рд┐рдП рдЬреЛ рд╕реНрдЯреИрдВрд╕рд┐рд▓ рдмрдлрд░ рдХреЛ рд▓рд┐рдЦрддреЗ рд╣реИрдВ, рдЖрдк рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рдзрд╛рд░рд╛ рдХреЛ рдорд╛рд░ рд╕рдХрддреЗ рд╣реИрдВ:
if(want to kill thread) return;
рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдЬрд┐рди рдзрд╛рд░рд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдЖрдкрдиреЗ рд░рд┐рдЯрд░реНрди рдХрд┐рдпрд╛ рдерд╛, рд╡реЗ рдореБрдЦреМрдЯрд╛ рд╣реЛ рдЬрд╛рдПрдВрдЧреЗ рдФрд░ __ballot () рдЗрд╕рдХреЗ рдкрд░рд┐рдгрд╛рдо рдореЗрдВ рд╕рдВрдмрдВрдзрд┐рдд рдмрд┐рдЯреНрд╕ рдХреЗ рд▓рд┐рдП рд╢реВрдиреНрдп рд╡рд╛рдкрд╕ рдЖ рдЬрд╛рдПрдЧрд╛ред рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдПрдХ рд╕реВрдХреНрд╖реНрдорддрд╛ рд╣реИред рдХрдо рд╕реЗ рдХрдо рддрд╛рдирд╛ рдХреЗ рдЕрдВрджрд░ рдПрдХ рд╢реВрдиреНрдп рдкреНрд░рд╡рд╛рд╣ рдХреЗ рд▓рд┐рдП, рдЖрдк рдРрд╕рд╛ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ, рдЕрдиреНрдпрдерд╛ рдкрд░рд┐рдгрд╛рдо рдмрд╕ рд╡рд╛рдкрд╕ рдирд╣реАрдВ рд▓рд┐рдЦрд╛ рдЬрд╛рдПрдЧрд╛ред рдЗрд╕рд▓рд┐рдП, рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдЖрдк рдХреЗрд╡рд▓ рдРрд╕рд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ
if(want to kill thread && (tid&0x1f!=0)) return;
рдпрд╛ рдКрдкрд░ рджрд┐рдП рдЧрдП рдлреЙрд░реНрдо рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ:
if(want to kill thread) { active = 0; goto WRITE_BACK_STENCIL_DATA; }
рдкреБрд░рд╛рдиреЗ рд╣рд╛рд░реНрдбрд╡реЗрдпрд░ рдХреЗ рд▓рд┐рдП рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╕реБрд╡рд┐рдзрд╛рдПрдБ (G80-GT200)
рдЖрдЗрдП рдЕрдм рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ рдХрд┐ рд╕реНрдЯреИрдВрд╕рд┐рд▓ рдХреЗ рд▓рд┐рдП рдкреБрд░рд╛рдиреЗ рдЬреАрдкреАрдпреВ рдкрд░ рдкреНрд░рднрд╛рд╡реА рдврдВрдЧ рд╕реЗ рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреНрдпрд╛ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рдЗрди рд╡реАрдбрд┐рдпреЛ рдХрд╛рд░реНрдб рдкрд░ __ballot () рдлрд╝рдВрдХреНрд╢рди рд╕рдорд░реНрдерд┐рдд рдирд╣реАрдВ рд╣реИред рд╣рдо рдЕрдкрдиреЗ рдкрд╛рд╕ рдореМрдЬреВрдж рдХреНрд╖рдорддрд╛рдУрдВ рдХреЗ рдЕрдиреБрд╕рд╛рд░ WriteStencilBit рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрддреЗ рд╣реИрдВ:
template<int CURR_BLOCK_SIZE> __device__ inline void WriteStencilBit(int tid, uint* a_stencilBuffer, uint value) { #if COMPUTE_CAPABILITY >= COMPUTE_CAPABILITY_GF100 uint stencilMask = __ballot(value); if((tid & 0x1f) == 0) a_stencilBuffer[tid >> 5] = stencilMask; #elif COMPUTE_CAPABILITY >= COMPUTE_CAPABILITY_GT200 if(__all(value==0)) { if((tid & 0x1f) == 0) a_stencilBuffer[tid >> 5] = 0; } else if(__all(value)) { if((tid & 0x1f) == 0) a_stencilBuffer[tid >> 5] = 0xffffffff; } else { __shared__ uint active_threads[CURR_BLOCK_SIZE/32]; uint* pAddr = active_threads + (threadIdx.x >> 5); if((tid & 0x1f) == 0) *pAddr = 0; atomicOr(pAddr, value); if((tid & 0x1f) == 0) a_stencilBuffer[tid >> 5] = *pAddr; } #else __shared__ uint active_threads[CURR_BLOCK_SIZE]; active_threads[threadIdx.x] = value; if((threadIdx.x & 0x1) == 0) active_threads[threadIdx.x] = value | active_threads[threadIdx.x+1]; if((threadIdx.x & 0x3) == 0) active_threads[threadIdx.x] = active_threads[threadIdx.x] | active_threads[threadIdx.x+2]; if((threadIdx.x & 0x7) == 0) active_threads[threadIdx.x] = active_threads[threadIdx.x] | active_threads[threadIdx.x+4]; if((threadIdx.x & 0xf) == 0) active_threads[threadIdx.x] = active_threads[threadIdx.x] | active_threads[threadIdx.x+8]; if((threadIdx.x & 0x1f) == 0) active_threads[threadIdx.x] = active_threads[threadIdx.x] | active_threads[threadIdx.x+16]; uint* perWarpArray = active_threads + ((threadIdx.x >> 5) << 5); if((tid & 0x1f) == 0) a_stencilBuffer[tid >> 5] = perWarpArray[0]; #endif }
рдЗрд╕ рдкреНрд░рдХрд╛рд░ рд╣рдо рд╕рд╛рдЭрд╛ рдореЗрдореЛрд░реА + 2 рдорддрджрд╛рди рдХрд╛рд░реНрдпреЛрдВ рдореЗрдВ рдкрд░рдорд╛рдгреБ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ, __any рдФрд░ __all рдЙрдкрд▓рдмреНрдз рд╣реИрдВ, рддрд╛рдХрд┐ рд╣рдо рдЙрдирдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХреЗрдВред рдЕрдиреНрдп рдорд╛рдорд▓реЛрдВ рдореЗрдВ, рдХреЗрд╡рд▓ рд╢рд╛рд╕реНрддреНрд░реАрдп рдХрдореА рдмрдиреА рд╣реБрдИ рд╣реИред
рд╕реНрдЯреИрдВрд╕рд┐рд▓ рдХрд╛ рдкрд░реАрдХреНрд╖рдг
рдХрд┐рд░рдг рдЕрдиреБрд░реЗрдЦрдг рдХреА рдЬрд░реВрд░рддреЛрдВ рдХреЗ рд▓рд┐рдП, рдЗрд╕ рддрд░рд╣ рдХреЗ рдПрдХ рд╕реНрдЯреИрдВрд╕рд┐рд▓ рдмрдлрд░ рдмрд╣реБрдд рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рдЖрдпрд╛ рдерд╛ред рдЕрдкрдиреЗ рдкреБрд░рд╛рдиреЗ рд▓реИрдкрдЯреЙрдк рдХреЗ GTX560 рдкрд░, рдореБрдЭреЗ рдкреНрд░рддрд┐ рд╕реЗрдХрдВрдб рд▓рдЧрднрдЧ 4 рдмрд┐рд▓рд┐рдпрди рдХрд░реНрдиреЗрд▓ рдХреЙрд▓ рдорд┐рд▓рддреЗ рд╣реИрдВ (рдпрд╛рдиреА, 4 рдмрд┐рд▓рд┐рдпрди рдЦрд╛рд▓реА рдХреЙрд▓ рдкреНрд░рддрд┐ рд╕реЗрдХрдВрдб) - рдмреБрд░рд╛ рдирд╣реАрдВ рд╣реИ, рд╣реИ рдирд╛? рдЯреНрд░реЗрд╕ рдбреЗрдкреНрде рдмрдврд╝рдиреЗ рдХреЗ рд╕рд╛рде, рдкреНрд░рджрд░реНрд╢рди рдХрд┐рддрдиреА рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд╡рд╕реНрддреБрдУрдВ рдореЗрдВ рдкрд░рд┐рд▓рдХреНрд╖рд┐рдд рд╣реЛрддрд╛ рд╣реИ, рдЗрд╕рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдереЛрдбрд╝рд╛ рдЧрд┐рд░рд╛ред рдЯреЗрд╕реНрдЯ рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рд╕рд░рд▓рддрдо рдЪрд┐рдВрддрдирд╢реАрд▓ рджреГрд╢реНрдп рдкрд░ рдХрд┐рдП рдЧрдП:

рдПрдлрдкреАрдПрд╕ рдХреА рдЧрддрд┐рд╢реАрд▓рддрд╛ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рд╣реИ: 30, 25, 23.7, 20, 19.4, 18.8