• (低)除法中,如果除數是二的次方數,可以轉換成 bitwise operation,例如: i/1024 轉成 i >> 10、i%64 轉成 i & 63。若在程式中寫的是常數,則編譯時會自動轉換。
  • 開根號再倒數可使用 rsqrtf() (float)或 rsqrt() (double)
  • (中)如果速度比精確度重要,可使用 fast math library。以下範例為精確度的展示:
    #include<stdio.h>
    #include<math.h>
    
    #define SIZE 100000
    
    __global__ static void sineTest(float *out){
    	out[0] = sinf(0.5);
    	out[1] = __sinf(0.5);
    }
    
    int main(int argc,char **argv)
    {
    	float out[3], *gpu_out;
    
    	cudaMalloc((void**)&gpu_out, sizeof(float) * 2);
    	
    	sineTest<<<1, 2>>>(gpu_out);
    	out[2] = sin(0.5);
    	cudaThreadSynchronize();
    	
    	cudaMemcpy(out, gpu_out, sizeof(int) * 2, cudaMemcpyDeviceToHost);
    	
    	printf("GPU vs GPU-fast: %f\n", log10(fabs(out[0]-out[1])));
    	printf("GPU vs CPU: %f\n", log10(fabs(out[0]-out[2])));
    	printf("GPU-fast vs CPU: %f\n", log10(fabs(out[1]-out[2])));
    	
    	return 0;
    }
    
  • (中)以特化的、較快的函式,取代較慢的、較一般的函式
    • 比較小的整數次方,以直接用乘的取代 pow()
    • 底數為 2 或 10 的次方,用 exp2()、expf2()、exp10()、expf10() 取代 pow()、powf()
    • 指數為 1/3 時,用 cbrt() 或 cbrtf()
    • 計算 sin(pi*x) 時,使用 sinpi() 或 sinpif()
  • (高)減少 global memory 的使用,盡量用 shared memory