CUDA: рд╡рд┐рд╢рд┐рд╖реНрдЯ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рдкреНрд░рджрд░реНрд╢рди рдкрд╣рд▓реБрдУрдВ

рдЗрд╕рд╕реЗ рдкрд╣рд▓реЗ рдХрд┐ рдЖрдк рдПрдХ рдХрдореНрдкреНрдпреВрдЯреЗрд╢рдирд▓ рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рд╡реАрдбрд┐рдпреЛ рдХрд╛рд░реНрдб рдореЗрдВ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░реЗрдВ, рдЖрдкрдХреЛ рдпрд╣ рд╡рд┐рдЪрд╛рд░ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП рдХрд┐ рдХреНрдпрд╛ рд╣рдореЗрдВ рд╡рд╛рдВрдЫрд┐рдд рдкреНрд░рджрд░реНрд╢рди рд▓рд╛рдн рдорд┐рд▓реЗрдЧрд╛ рдпрд╛ рд╕рдордп рдирд╣реАрдВ рдЧрдВрд╡рд╛рдирд╛ рдкрдбрд╝реЗрдЧрд╛ред рдФрд░ рдирд┐рд░реНрдорд╛рддрд╛рдУрдВ рдХреЗ рд╕реИрдХрдбрд╝реЛрдВ GFLOPS рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╡рд╛рджреЛрдВ рдХреЗ рдмрд╛рд╡рдЬреВрдж, рдХрд╛рд░реНрдб рдХреА рд╡рд░реНрддрдорд╛рди рдкреАрдврд╝реА рдХреА рдЕрдкрдиреА рд╕рдорд╕реНрдпрд╛рдПрдВ рд╣реИрдВ, рдЬреЛ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд╕рдмрд╕реЗ рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рдЬрд╛рдиреА рдЬрд╛рддреА рд╣реИрдВред рдореИрдВ рд╕рд┐рджреНрдзрд╛рдВрдд рдореЗрдВ рдЧрд╣рд░рд╛рдИ рд╕реЗ рдирд╣реАрдВ рдЬрд╛рдКрдВрдЧрд╛ рдФрд░ рдХреБрдЫ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рдмрд┐рдВрджреБрдУрдВ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реВрдВрдЧрд╛ рдФрд░ рдХреБрдЫ рдЙрдкрдпреЛрдЧреА рдирд┐рд╖реНрдХрд░реНрд╖ рддреИрдпрд╛рд░ рдХрд░реВрдВрдЧрд╛ред

рдорд╛рди рд▓реЗрдВ рдХрд┐ рдЖрдкрдиреЗ рд▓рдЧрднрдЧ рдпрд╣ рдкрддрд╛ рд▓рдЧрд╛ рд▓рд┐рдпрд╛ рд╣реИ рдХрд┐ CUDA рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ рдФрд░ CUDA рдЯреВрд▓рдХрд┐рдЯ рдХреЗ рд╕реНрдерд┐рд░ рд╕рдВрд╕реНрдХрд░рдг рдХреЛ рдкрд╣рд▓реЗ рд╣реА рдбрд╛рдЙрдирд▓реЛрдб рдХрд░ рдЪреБрдХрд╛ рд╣реИред

рдореИрдВ рдЕрдм рдХреЛрд░ рдбреБрдУ E8400 рдкрд░ рдорд┐рдбрд┐рд▓-рдПрдВрдб GTX460 рдЧреНрд░рд╛рдлрд┐рдХреНрд╕ рдХрд╛рд░реНрдб рдХреЛ рдкреАрдбрд╝рд╛ рджреЗрдЧрд╛ред

рдлрдВрдХреНрд╢рди рдХреЙрд▓

рд╣рд╛рдВ, рдпрджрд┐ рд╣рдо рдХреБрдЫ рдЧрдгрдирд╛ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рд╣рдо рдХрд╛рд░реНрдб рдкрд░ рдХрд┐рдП рдЧрдП рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХреЙрд▓ рдХрд┐рдП рдмрд┐рдирд╛ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рд╕рдмрд╕реЗ рд╕рд░рд▓ рдкрд░реАрдХреНрд╖рдг рдлрд╝рдВрдХреНрд╢рди рд▓рд┐рдЦрддреЗ рд╣реИрдВ:

__global__ void stubCUDA( unsigned short * output)
{
// the most valid function: yep, does nothing.
}

рдЖрдкрдХреЛ рдпрд╛рдж рджрд┐рд▓рд╛ рджреВрдВ рдХрд┐ __global__ Specier рдЖрдкрдХреЛ рд╕реАрдкреАрдпреВ рд╕реЗ рдХреЙрд▓ рдХрд░рдХреЗ GPU рдкрд░ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ:
cudaThreadSynchronize();
stubCUDA<<<GRID, THREADS>>>(0);
cudaThreadSynchronize();

рд╕рднреА рдлрд╝рдВрдХреНрд╢рди рдХреЙрд▓ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рд╣реЛрддреЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП cudaThreadSynchronize () рдХреЙрд▓ рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкреВрд░реНрдг рд╣реЛрдиреЗ рдХреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред

рдЖрдЗрдП рдЗрд╕ рддрд░рд╣ рдХреЗ рдмреНрд▓реЙрдХ рдХреЛ рд▓реВрдк рдореЗрдВ рдЪрд▓рд╛рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВ: рд╣рдореЗрдВ GRID = 160, THREADS = 96 рдХреЗ рд▓рд┐рдП рдкреНрд░рддрд┐ рд╕реЗрдХрдВрдб рд▓рдЧрднрдЧ 15,000 рдХреЙрд▓ рдорд┐рд▓рддреЗ рд╣реИрдВред

рдорд╛рди рд▓реЗрдВ рдХрд┐ рдпрд╣ рдмрд┐рд▓рдХреБрд▓ рднреА рдореЛрдЯрд╛ рдирд╣реАрдВ рд╣реИред рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рд╕рдмрд╕реЗ рд╕рд░рд▓ рдХрд╛рд░реНрдп, рдЬреЛ рдХреБрдЫ рднреА рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, 0.7 рдПрдордПрд╕ рд╕реЗ рдЕрдзрд┐рдХ рддреЗрдЬреА рд╕реЗ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛ рд╣реИред

рдкрд╣рд▓реА рдзрд╛рд░рдгрд╛ рдпрд╣ рд╣реИ рдХрд┐ рдЬреНрдпрд╛рджрд╛рддрд░ рд╕рдордп рдереНрд░реЗрдб рд╕рд┐рдВрдХреНрд░реЛрдирд╛рдЗрдЬрд╝реЗрд╢рди рдкрд░ рдЦрд░реНрдЪ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдПрд╕рд┐рдВрдХреНрд░реЛрдирд╕ рдХреЙрд▓ рдмрд╣реБрдд рддреЗрдЬреА рд╕реЗ рдХрд╛рдо рдХрд░реЗрдВрдЧреЗ (рд╣рд╛рд▓рд╛рдВрдХрд┐ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдХрд╛рд░реНрдпреЛрдВ рдореЗрдВ рдЙрдирдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЕрдзрд┐рдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╣реИ)ред

рдЗрд╕рдХреА рдЬрд╛рдБрдЪ рдХрд░реЗрдВред рд╕рд┐рдВрдХреНрд░рдирд╛рдЗрдЬрд╝реЗрд╢рди рдХреЗ рдмрд┐рдирд╛, рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдкреНрд░рддрд┐ рд╕реЗрдХрдВрдб 73100 рдмрд╛рд░ рдЪрд▓рд╛рдирд╛ рд╕рдВрднрд╡ рдерд╛ред рдкрд░рд┐рдгрд╛рдо, рдпрд╣ рдзреНрдпрд╛рди рджрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП, рдмрд┐рд▓реНрдХреБрд▓ рдкреНрд░рднрд╛рд╡рд╢рд╛рд▓реА рдирд╣реАрдВ рд╣реИред

рдФрд░ рдЕрдВрддрд┐рдо рдкрд░реАрдХреНрд╖рдг, рдЪрд▓реЛ рдлрд╝рдВрдХреНрд╢рди рдХреЛ GRID = THREADS = 1 рдХреЗ рд╕рд╛рде рдЪрд▓рд╛рддреЗ рд╣реИрдВ, рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдХрд╛рд░реНрдб рдХреЗ рдЕрдВрджрд░ рдереНрд░реЗрдб рдХрд╛ рдПрдХ рдЧреБрдЪреНрдЫрд╛ рдмрдирд╛рдиреЗ рдХреЗ рдУрд╡рд░рд╣реЗрдб рдХреЛ рд╕рдорд╛рдкреНрдд рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред рд▓реЗрдХрд┐рди рдРрд╕рд╛ рдирд╣реАрдВ рд╣реИ, рд╣рдореЗрдВ рдкреНрд░рддрд┐ рд╕реЗрдХрдВрдб рд╕рдорд╛рди 73000-73500 рдХреЙрд▓ рдорд┐рд▓рддреЗ рд╣реИрдВред

рддреЛ рдиреИрддрд┐рдХ:

рдмрд╛рд╣рд░реА рдореЗрдореЛрд░реА рдПрдХреНрд╕реЗрд╕

рдХреБрдЫ рдЙрдкрдпреЛрдЧреА рдЦреЛрдЬрдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдЗрдирдкреБрдЯ рдФрд░ рдЖрдЙрдЯрдкреБрдЯ рдбреЗрдЯрд╛ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдпрд╣ рд╕рдордЭрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдХрд┐ рдХрд┐рддрдиреА рддреЗрдЬреА рд╕реЗ рдбреЗрдЯрд╛ рдХреЛ рд╡реАрдбрд┐рдпреЛ рдХрд╛рд░реНрдб рд╕реЗ / рд╕реЗ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд░рд╣рд╛ рд╣реИред рд╣рдо рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ:
cudaMemcpy(data_cuda, image, data_cuda_size, cudaMemcpyHostToDevice);

рд╣рд╛рдВ, CUDA рд╣рдореЗрдВ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдбреЗрдЯрд╛ рдЯреНрд░рд╛рдВрд╕рдорд┐рд╢рди рдЯреВрд▓ рднреА рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЙрдирдХрд╛ рдкреНрд░рджрд░реНрд╢рди, рдЖрдЧреЗ рджреЗрдЦрддреЗ рд╣реБрдП, рд╕рд┐рдВрдХреНрд░реЛрдирд╕ рдлрд╝рдВрдХреНрд╢рди рд╕реЗ рднрд┐рдиреНрди рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИред

рд╣рдо рдмрдбрд╝реЗ рдмреНрд▓реЙрдХреНрд╕ рдХреА рдирдХрд▓ рдХрд░рддреЗ рд╣реИрдВ: рдЬреИрд╕реЗ cudaMemcpyHostToDevice, рдФрд░ cudaMemcpyDeviceToHost рдХреА рджрд┐рд╢рд╛ рдореЗрдВ рд╣рдореЗрдВ рдмрдбрд╝реЗ рдмреНрд▓реЙрдХ (100 рдореЗрдЧрд╛рдЯрди рд╕реЗ рдЕрдзрд┐рдХ) рдкрд░ рд▓рдЧрднрдЧ 2 GB / s рдХрд╛ рдкреНрд░рджрд░реНрд╢рди рдорд┐рд▓рддрд╛ рд╣реИред рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рдпрд╣ рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рд╣реИред

рдмрд╣реБрдд рдЫреЛрдЯреА рд╕рдВрд░рдЪрдирд╛рдУрдВ рдХреЗ рд╕рд╛рде рд╣рд╛рд▓рд╛рдд рдмрд╣реБрдд рдЦрд░рд╛рдм рд╣реИрдВред 4 рдмрд╛рдЗрдЯреНрд╕ рдЯреНрд░рд╛рдВрд╕рдорд┐рдЯ рдХрд░рдХреЗ , рд╣рдореЗрдВ рдкреНрд░рддрд┐ рд╕реЗрдХрдВрдб 22,000 рд╕реЗ рдЕрдзрд┐рдХ рдХреЙрд▓ рдирд╣реАрдВ рдорд┐рд▓рддреЗ рд╣реИрдВ, рдЕрд░реНрдерд╛рддреНред 88 рдХреЗрдмреА / рдПрд╕ ред

рдиреИрддрд┐рдХ:

рдЖрдВрддрд░рд┐рдХ рдореЗрдореЛрд░реА рдПрдХреНрд╕реЗрд╕

рд╣рдордиреЗ рдбреЗрдЯрд╛ рдХреЛ рдХрд╛рд░реНрдб рдореЗрдВ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рдЖрдк рдЙрдирдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдореИрдВ рд╡реАрдбрд┐рдпреЛ рдореЗрдореЛрд░реА рддрдХ рдкрд╣реБрдВрдЪ рдХреА рдЕрдиреБрдорд╛рдирд┐рдд рдЧрддрд┐ рдХрд╛ рдореВрд▓реНрдпрд╛рдВрдХрди рдХрд░рдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛ред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдлрд╝рдВрдХреНрд╢рди рд▓рд┐рдЦрддреЗ рд╣реИрдВ:
__global__ void accessTestCUDA(unsigned short * output, unsigned short * data, int blockcount, int blocksize)
{
// just for test of max access speed: does nothing useful
unsigned short temp;
for ( int i = blockIdx.x; i < blockcount; i += gridDim.x)
{
int vectorBase = i * blocksize;
int vectorEnd = vectorBase + blocksize;

for ( int j = vectorBase + threadIdx.x; j < vectorEnd; j += blockDim.x)
{
temp = data[j];
}
}
output[0] = temp;
}


GRID рдФрд░ THREADS рдкреИрд░рд╛рдореАрдЯрд░ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдпрд╣рд╛рдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ, рдЬрдм рддрдХ рдХрд┐ рдореИрдВ рдХреНрдпреЛрдВ рд╕рдордЭрд╛рддрд╛ рд╣реВрдВ, рд▓реЗрдХрд┐рди рдореЗрд░рд╛ рд╡рд┐рд╢реНрд╡рд╛рд╕ рдХрд░реЛ - рд╕рдм рдХреБрдЫ рд╡реИрд╕рд╛ рд╣реА рд╣реИ рдЬреИрд╕рд╛ рдХрд┐ рдпрд╣ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рдкрд┐рдХреА рдХрд╣реЗрдЧрд╛ рдХрд┐ рд╕рд┐рдВрдХреНрд░рдирд╛рдЗрдЬрд╝реЗрд╢рди рдХреА рдХрдореА рдХреЗ рдХрд╛рд░рдг рдкрд░рд┐рдгрд╛рдо рдЧрд▓рдд рддрд░реАрдХреЗ рд╕реЗ рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рд╣рдореЗрдВ рдЗрд╕рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред

рдЗрд╕рд▓рд┐рдП, рд╣рдореЗрдВ рдордирдорд╛рдиреА рдкрдврд╝рдиреЗ рдХреЗ рд▓рд┐рдП рд▓рдЧрднрдЧ 42 рдЬреАрдмреА / рдПрд╕ рдорд┐рд▓рддрд╛ рд╣реИред рдпрд╣ рдмрд┐рд▓реНрдХреБрд▓ рднреА рдмреБрд░рд╛ рдирд╣реАрдВ рд╣реИред

рдЕрдм рд╣рдо рдлрд╝рдВрдХреНрд╢рди рдХреЛ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░рддреЗ рд╣реИрдВ рддрд╛рдХрд┐ рдпрд╣ рдЗрдирдкреБрдЯ рдбреЗрдЯрд╛ рдХреЛ рдЖрдЙрдЯрдкреБрдЯ рдореЗрдВ рдХреЙрдкреА рдХрд░ рджреЗред рдЗрд╕рдХрд╛ рдХреЛрдИ рдорддрд▓рдм рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдЖрдкрдХреЛ рд╡реАрдбрд┐рдпреЛ рдореЗрдореЛрд░реА рдореЗрдВ рд░рд┐рдХреЙрд░реНрдбрд┐рдВрдЧ рдХреА рдЧрддрд┐ рдХрд╛ рдореВрд▓реНрдпрд╛рдВрдХрди рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ (рдЪреВрдВрдХрд┐ рдкрд░рд┐рд╡рд░реНрддрди рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╕рд░рд▓ рд╣реИ, рдореИрдВ рдХреЛрдб рдХреА рдирдХрд▓ рдирд╣реАрдВ рдХрд░реВрдВрдЧрд╛)ред

I / O рдХреЗ рд▓рд┐рдП рд╣рдореЗрдВ рд▓рдЧрднрдЧ 30 GB / s рдорд┐рд▓рддреЗ рд╣реИрдВред рдмреБрд░рд╛ рднреА рдирд╣реАрдВ рд╣реИред

рдпрд╣ рд╕рд╣реА рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП рдХрд┐ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд╣рдордиреЗ рдЕрдиреБрдХреНрд░рдорд┐рдХ (рдХреБрдЫ рд╡рд┐рдЪрд▓рди рдХреЗ рд╕рд╛рде) рдореЗрдореЛрд░реА рдПрдХреНрд╕реЗрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдерд╛ред рдПрдХ рдордирдорд╛рдирд╛ рдЖрдВрдХрдбрд╝рд╛ рджреЛ рдЧреБрдирд╛ рддрдХ рдмрд┐рдЧрдбрд╝ рд╕рдХрддрд╛ рд╣реИ - рд▓реЗрдХрд┐рди рдХреНрдпрд╛ рдпрд╣ рдХреЛрдИ рд╕рдорд╕реНрдпрд╛ рдирд╣реАрдВ рд╣реИ?

рдиреИрддрд┐рдХ:

рдЕрдВрдХрдЧрдгрд┐рдд рд╕рдВрдЪрд╛рд▓рди

рд╣рдо рдмрд╣реБрдд рд╣реА рд╕рд░рд▓ рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХреЛ рдЫреЛрдбрд╝рддреЗ рд╣реИрдВ рдФрд░ рдХреБрдЫ рдЙрдкрдпреЛрдЧреА рдХрд░рддреЗ рд╣реИрдВред рдЕрд░реНрдерд╛рддреН, рдЫрд╡рд┐ рд╕рд╛рдорд╛рдиреНрдпреАрдХрд░рдг (рдкрд┐рдХреНрд╕реЗрд▓ [t]: = (рдкрд┐рдХреНрд╕реЗрд▓ [t] -sub) * рдХрд╛рд░рдХ)ред рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдХреЛрдб:
__global__ void normalizeCUDA(unsigned short * data, int blockcount, int blocksize, float sub, float factor)
{
for ( int i = blockIdx.x; i < blockcount; i += gridDim.x)
{
int vectorBase = i * blocksize;
int vectorEnd = vectorBase + blocksize;

for ( int j = vectorBase + threadIdx.x; j < vectorEnd; j += blockDim.x)
{
register float d = ( float )data[j];
d = (d - sub) * factor;
data[j] = (unsigned short )d;
}
}
}


рдпрд╣рд╛рдВ, рддреАрди рдХреЗ рд░реВрдк рдореЗрдВ рдХрдИ рдЙрдЪрд┐рдд рд░реВрдк рд╕реЗ рдХрдореНрдкреНрдпреВрдЯреЗрд╢рдирд▓ рдкреНрд░рдХреНрд░рд┐рдпрд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ: рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд╕рдВрдЦреНрдпрд╛, ADDMUL рдФрд░ рдкреВрд░реНрдгрд╛рдВрдХ рдХреЗ рд▓рд┐рдП рдХрд╛рд╕реНрдЯрд┐рдВрдЧред рдлрд╝реЛрд░рдо рдбрд░рд╛рддрд╛ рд╣реИ рдХрд┐ рдкреВрд░реА рд╕рд╛рдордЧреНрд░реА рдХреЛ рдХрд╛рд╕реНрдЯрд┐рдВрдЧ рдмрд╣реБрдд рдмреБрд░реА рддрд░рд╣ рд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред рд╢рд╛рдпрдж рдпрд╣ рдкреБрд░рд╛рдиреА рдкреАрдврд╝реА рдХреЗ рдХрд╛рд░реНрдб рдХреЗ рд▓рд┐рдП рд╕рдЪ рдерд╛, рд▓реЗрдХрд┐рди рдЕрдм рдРрд╕рд╛ рдирд╣реАрдВ рд╣реИред

рдХреБрд▓ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдЧрддрд┐: 26 рдЬреАрдмреА / рдПрд╕ ред рдХреЗрд╡рд▓ 13% рджреНрд╡рд╛рд░рд╛ I / O рдХреЛ рдирд┐рд░реНрджреЗрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рддреАрди рдСрдкрд░реЗрд╢рдиреЛрдВ рдиреЗ рдкреНрд░рджрд░реНрд╢рди рдХреЛ рдЦрд░рд╛рдм рдХрд░ рджрд┐рдпрд╛ред

рдпрджрд┐ рдЖрдк рдзреНрдпрд╛рди рд╕реЗ рдХреЛрдб рдХреЛ рджреЗрдЦрддреЗ рд╣реИрдВ, рддреЛ рдпрд╣ рд╕рд╛рдорд╛рдиреНрдп рд░реВрдк рд╕реЗ рд╕рд╣реА рдирд╣реАрдВ рд╣реИред рдкреВрд░реНрдгрд╛рдВрдХ рд▓рд┐рдЦрдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдХреЛ рдЧреЛрд▓ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рдЧреЛрд▓ () рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд╕рд╛рдеред рд▓реЗрдХрд┐рди рдРрд╕рд╛ рди рдХрд░реЗрдВ, рдФрд░ рдХрднреА рднреА рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рди рдХрд░реЗрдВ!

рджреМрд░ (рдбреА): 20 рдЬреАрдмреА / рдПрд╕ , рдПрдХ рдФрд░ рд╢реВрдиреНрдп рд╕реЗ 23%ред
(рдЕрд╣рд╕реНрддрд╛рдХреНрд╖рд░рд┐рдд рд▓рдШреБ) (рдбреА + 0.5): 26 рдЬреАрдмреА / рдПрд╕ , рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдорд╛рдк рддреНрд░реБрдЯрд┐ рдХреЗ рднреАрддрд░ рдХрд╛ рд╕рдордп рднреА рдирд╣реАрдВ рдмрджрд▓рд╛ рд╣реИред

рдиреИрддрд┐рдХ:

рддрд╛рд░реНрдХрд┐рдХ рд╕рдВрдЪрд╛рд▓рди

рдЖрдЗрдП рддрд╛рд░реНрдХрд┐рдХ рд╕рдВрдЪрд╛рд▓рди рдХреА рдЧрддрд┐ рдХрд╛ рдореВрд▓реНрдпрд╛рдВрдХрди рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВ, рдФрд░ рдЙрд╕реА рд╕рдордп рд╣рдо рдПрдХ рдФрд░ рдЕрдЪреНрдЫрд╛ рдХрд╛рдо рдХрд░реЗрдВрдЧреЗ: рд╣рдо рд╕рд░рдгреА рдореЗрдВ рдиреНрдпреВрдирддрдо рдФрд░ рдЕрдзрд┐рдХрддрдо рдорд╛рди рдкрд╛рдПрдВрдЧреЗред рдпрд╣ рдЪрд░рдг рдЖрдо рддреМрд░ рдкрд░ рд╕рд╛рдорд╛рдиреНрдпреАрдХрд░рдг рд╕реЗ рдкрд╣рд▓реЗ рд╣реЛрддрд╛ рд╣реИ (рдФрд░ рдпрд╣ рд╕рд┐рд░реНрдл рдЗрд╕рдХреЗ рд▓рд┐рдП рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рдерд╛), рд▓реЗрдХрд┐рди рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЗрд╕рдХреЗ рд╡рд┐рдкрд░реАрдд рд╣реЛрдЧрд╛ - рдХреНрдпреЛрдВрдХрд┐ рд╡рд╣ рдХрдард┐рди рд╣реИред рдпрд╣рд╛рдБ рдХрд╛рдо рдХрд░ рдХреЛрдб рд╣реИ:
__global__ void getMinMaxCUDA(unsigned short * output, unsigned short * data, int blockcount, int blocksize)
{
__shared__ unsigned short sMins[MAX_THREADS];
__shared__ unsigned short sMaxs[MAX_THREADS];

sMins[threadIdx.x] = data[0];
sMaxs[threadIdx.x] = data[0];

for ( int i = blockIdx.x; i < blockcount; i += gridDim.x)
{
int vectorBase = i * blocksize;
int vectorEnd = vectorBase + blocksize;

for ( int j = vectorBase + threadIdx.x; j < vectorEnd; j += blockDim.x)
{
register unsigned short d = data[j];
if (d < sMins[threadIdx.x])
sMins[threadIdx.x] = d;
if (d > sMaxs[threadIdx.x])
sMaxs[threadIdx.x] = d;
}
}

__syncthreads();

if (threadIdx.x == 0)
{
register unsigned short min = sMins[0];
for ( int j = 1; j < blockDim.x; j++)
if (sMins[j] < min)
min = sMins[j];
if (min < output[0])
output[0] = min;
}

if (threadIdx.x == 1)
{
register unsigned short max = sMaxs[0];
for ( int j = 1; j < blockDim.x; j++)
if (sMaxs[j] > max)
max = sMaxs[j];
if (max > output[1])
output[1] = max;
}

__syncthreads();
}


рдпрд╣рд╛рдВ рдЖрдк рдереНрд░реЗрдбреНрд╕ рдФрд░ рд╕рд╛рдЭрд╛ рдХреА рдЧрдИ рдореЗрдореЛрд░реА рдХреЗ рд╕рд┐рдВрдХреНрд░рдирд╛рдЗрдЬрд╝реЗрд╢рди рдХреЗ рдмрд┐рдирд╛ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗред

рдХреБрд▓ рдЧрддрд┐: 29 рдЬреАрдмреА / рдПрд╕ , рд╕рд╛рдорд╛рдиреНрдп рд╕реЗ рднреА рддреЗрдЬред

рдореИрдВрдиреЗ рдиреНрдпреВрдирддрдо рдФрд░ рдЕрдзрд┐рдХрддрдо рдХреЛрдб рдХреНрдпреЛрдВ рдЬреЛрдбрд╝рд╛ - рджреЛрдиреЛрдВ рдХреА рдЖрдорддреМрд░ рдкрд░ рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рдФрд░ рдХреЙрд▓ рдЕрд▓рдЧ рд╕реЗ рд╕рдордп рдЦреЛ рджреЗрддреЗ рд╣реИрдВ (рдкрд╣рд▓реЗ рдкреИрд░рд╛рдЧреНрд░рд╛рдл рджреЗрдЦреЗрдВ)ред

рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рдПрдХ рдкрддреНрдерд░ рдХреЛ рдЙрд╕ рдкрд░ рдлреЗрдВрдХ рджреЗрдВ рдЬрд┐рд╕рдиреЗ рдХрд╣рд╛ рдерд╛ рдХрд┐ рд╡реАрдбрд┐рдпреЛ рдХрд╛рд░реНрдб рд╕рд╢рд░реНрдд рд╕рдВрдЪрд╛рд▓рди рдХреЗ рд╕рд╛рде рдЦрд░рд╛рдм рд╣реИрдВ: рдХреГрддреНрд░рд┐рдо рд░реВрдк рд╕реЗ рд▓рдЧрднрдЧ 2 рдмрд╛рд░ рдЗрд╕ рдЯреБрдХрдбрд╝реЗ рдХреЛ рдзреАрдорд╛ рдХрд░рдиреЗ рдореЗрдВ рдХрд╛рдордпрд╛рдм рд░рд╣реЗ, рд▓реЗрдХрд┐рди рдЗрд╕рдХреЗ рд▓рд┐рдП рд╢рд░реНрддреЛрдВ рдХреА рдЧрд╣рд░рд╛рдИ рдХреЛ 4 рддрдХ рдмрдврд╝рд╛рдирд╛ рдЖрд╡рд╢реНрдпрдХ рдерд╛! if () if () if () if () if () ...

рдиреИрддрд┐рдХ:

рдЬрдЯрд┐рд▓ рдбреЗрдЯрд╛ рд╕рдВрд░рдЪрдирд╛рдПрдВ

рдЗрд╕ рд╡рд┐рдЪрд╛рд░ рд╕реЗ рдкреНрд░реЗрд░рд┐рдд рдХрд┐ рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдФрд░ рдбреЗрдЯрд╛ рд╕рдВрд░рдЪрдирд╛рдПрдВ рджреГрдврд╝рддрд╛ рд╕реЗ рдЬреБрдбрд╝реА рд╣реБрдИ рд╣реИрдВ (рдХрдо рд╕реЗ рдХрдо рдПрдиред Wirth), рдЖрдкрдХреЛ рдпрд╣ рджреЗрдЦрдирд╛ рдЪрд╛рд╣рд┐рдП рдХрд┐ рдХреБрдЫ рдЬрдЯрд┐рд▓ рдбреЗрдЯрд╛ рд╕рдВрд░рдЪрдирд╛рдУрдВ рдХреЗ рд╕рд╛рде рдЪреАрдЬреЗрдВ рдХреИрд╕реЗ рд╣реИрдВред

рдпрд╣ рд╡рд╣ рдЬрдЧрд╣ рд╣реИ рдЬрд╣рд╛рдВ рд╕рдорд╕реНрдпрд╛ рдЙрддреНрдкрдиреНрди рд╣реЛрддреА рд╣реИ, рдбреЗрдЯрд╛ рдХреЛ рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рддреЗ рд╕рдордп, рд╣рдо рдХреЗрд╡рд▓ рджреЛ рдкреНрд░рдХрд╛рд░ рдХреА рд╡рд╕реНрддреБрдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ - рдирд┐рд░рдВрддрд░ рдЕрднрд┐рдиреНрди рдкреНрд░рдХрд╛рд░ (рдЕрдВрдХ) рдФрд░ рд╡реАрдбрд┐рдпреЛ рдореЗрдореЛрд░реА рдмреНрд▓реЙрдХреЛрдВ рдХреЗ рд▓рд┐рдВрдХред

рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рд▓рд┐рдВрдХ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдкреЗрдбрд╝реЛрдВ рдХреЗ рдирд┐рд░реНрдорд╛рдг рдХрд╛ рд╡рд┐рдЪрд╛рд░ рддреБрд░рдВрдд рд╢рд╛рдорд┐рд▓ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ:

рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдпрд╣ рд╕реНрдореГрддрд┐ рдХреЗ рдирд┐рд░рдВрддрд░ рдмреНрд▓реЙрдХ рдФрд░ рдЗрд╕ рдмреНрд▓реЙрдХ рдХреЗ рддрддреНрд╡реЛрдВ рдХреЗ рд╕рдВрджрд░реНрдн рдореЗрдВ рд╕рд░рдгреА рдХреЗ рд░реВрдк рдореЗрдВ рдЬрдЯрд┐рд▓ рдбреЗрдЯрд╛ рд╕рдВрд░рдЪрдирд╛рдУрдВ рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд░рд╣рддрд╛ рд╣реИред рддреЛ рдЖрдк рдЖрд╕рд╛рдиреА рд╕реЗ рдХрд┐рд╕реА рднреА рдбреЗрдЯрд╛ рдРрд░реЗ рдХреЗ рдКрдкрд░ рд╣реИрд╢ рдЯреЗрдмрд▓, рдЯреНрд░реА рдФрд░ рдЗрдВрдбреЗрдХреНрд╕ рд╕реНрдЯреНрд░рдХреНрдЪрд░ рдХреА рдХрд▓реНрдкрдирд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рдРрд╕реЗ рдЯреНрд░рд┐рдХреНрд╕ рдХреЗ рд▓рд┐рдП рдкреЗрдмреИрдХ - рдбрдмрд▓ рдЗрдВрдбреЗрдХреНрд╕рд┐рдВрдЧ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛:
for ( int j = vectorBase + threadIdx.x; j < vectorEnd; j += blockDim.x)
{
temp = data[index[j]+i];
}

рдпрд╣ рдЯреБрдХрдбрд╝рд╛ рд╕реВрдЪрдХрд╛рдВрдХ рдФрд░ рдбреЗрдЯрд╛ рдХреА рд╕рд╛рдордЧреНрд░реА рдФрд░ рдЖрдХрд╛рд░ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ 10 рд╕реЗ 30 рдЬреАрдмреА / рдПрд╕ рдХреА рдЧрддрд┐ рд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред рдЖрдк рдореЗрдореЛрд░реА рдЙрдкрдпреЛрдЧ рдХреЛ рдЕрдиреБрдХреВрд▓рд┐рдд рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ , рд▓реЗрдХрд┐рди рд╕рдмрд╕реЗ рдЕрдЪреНрдЫреА рд╕реНрдерд┐рддрд┐ рдореЗрдВ рднреА рд╣рдо рдкрд╣реБрдВрдЪ рдХреА рдЧрддрд┐ рдХрд╛ 25% рдЦреЛ рджреЗрддреЗ рд╣реИрдВред рдЯреНрд░рд┐рдкрд▓ рдЗрдВрдбреЗрдХреНрд╕ 40% -60% рдкреНрд░рджрд░реНрд╢рди рдХреЛ рдЦреЛрдиреЗ рдХреЗ рд╕рд╛рде рднреА рдмрджрддрд░ рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд░рддреЗ рд╣реИрдВред

рдЖрдЬ рд╣рдо рдмрд╣реБрдд рдХреБрдЫ рд╕рдордЭ рдЧрдП

рд╡реАрдбрд┐рдпреЛ рдХрд╛рд░реНрдб рдХреА рдХреНрд╖рдорддрд╛рдУрдВ рдХреЗ рдЙрдЪрд┐рдд рдЙрдкрдпреЛрдЧ рдХреЗ рд╕рд╛рде, рдЖрдк рдЫрд╡рд┐ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг, рдзреНрд╡рдирд┐, рд╡реАрдбрд┐рдпреЛ рдЬреИрд╕реЗ рдХрд╛рд░реНрдпреЛрдВ рдореЗрдВ рдЕрднреВрддрдкреВрд░реНрд╡ рдкреНрд░рджрд░реНрд╢рди рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ - рдЬрд╣рд╛рдБ рднреА рдмрдбрд╝реА рдорд╛рддреНрд░рд╛ рдореЗрдВ рдбреЗрдЯрд╛ рд╣реЛ, рдЪрддреБрд░ рдЕрдВрдХрдЧрдгрд┐рдд рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдФрд░ рдЬрдЯрд┐рд▓ рдбреЗрдЯрд╛ рд╕рдВрд░рдЪрдирд╛рдУрдВ рдХреА рдЕрдиреБрдкрд╕реНрдерд┐рддрд┐ред

рдпрджрд┐ рдЖрдк рд╡рд┐рд╖рдп рдХреЛ рдкрд╕рдВрдж рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдореИрдВ рд╡реАрдбрд┐рдпреЛ рдХрд╛рд░реНрдб рдкрд░ рдХрдИ рдЙрдкрдпреЛрдЧреА рд╡рд╕реНрддреБрдУрдВ рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреЗ рддрд░реАрдХреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░реВрдВрдЧрд╛: рджреВрд░рд╕реНрде рдорд╛рдирдЪрд┐рддреНрд░, рдЫрд╡рд┐ рдЖрдХреГрддрд┐ рд╡рд┐рдЬреНрдЮрд╛рди рдФрд░ рдЦреЛрдЬ рдЕрдиреБрдХреНрд░рдорд┐рдд рдФрд░ рдХреБрдЫ рджрд┐рд▓рдЪрд╕реНрдк рдбреЗрдЯрд╛ рд╕рдВрд░рдЪрдирд╛рдПрдВ рджрд┐рдЦрд╛рддреЗ рд╣реИрдВ рдЬреЛ рдкрд░реНрдпрд╛рдкреНрдд рддреЗрдЬреА рд╕реЗ рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рд╕рд┐рдВрдХреНрд░рдирд╛рдЗрдЬрд╝реЗрд╢рди рдХреЗ рд╕рд╛рде рдЕрдирд╛рд╡рд╢реНрдпрдХ рд╕рдорд╕реНрдпрд╛рдПрдВ рдкреИрджрд╛ рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ ред

Source: https://habr.com/ru/post/In119435/


All Articles