歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> CUDA Texture紋理存儲器 示例程序

CUDA Texture紋理存儲器 示例程序

日期:2017/3/1 10:24:18   编辑:Linux編程

紋理存儲器非常適合實現圖像處理和查找表,對大量數據的隨機訪問或非隨機訪問也有良好的加速效果。第一次接觸紋理存儲器,寫了以下一個小程序。

相關閱讀:

Ubuntu 11.10 上安裝CUDA開發環境 http://www.linuxidc.com/Linux/2012-04/58913.htm

Ubuntu 11.04 安裝 NVIDIA CUDA 4.0 RC2 http://www.linuxidc.com/Linux/2011-10/46304.htm

  1. /*
  2. * Copyright 徐洪志(西北農林科技大學.信息工程學院). All rights reserved.
  3. * Data: 2012-4-20
  4. */
  5. //
  6. // 此程序是演示了1D和2D紋理存儲器的使用
  7. #include <stdio.h>
  8. #include <cutil_inline.h>
  9. #include <iostream>
  10. using namespace std;
  11. texture<float> texRef1D; // 1D texture
  12. texture<float, 2> texRef2D; // 2D texture
  13. // 1D 紋理操作函數
  14. __global__ void Texture1D(float *dst, int w, int h)
  15. {
  16. int x = threadIdx.x + blockIdx.x * blockDim.x;
  17. int y = threadIdx.y + blockIdx.y * blockDim.y;
  18. int offset = x + y * blockDim.x * gridDim.x;
  19. if(x<w && y<h)
  20. dst[offset] = tex1Dfetch(texRef1D, offset);
  21. }
  22. // 2D 紋理操作函數
  23. __global__ void Texture2D(float *dst, int w, int h)
  24. {
  25. int x = threadIdx.x + blockIdx.x * blockDim.x;
  26. int y = threadIdx.y + blockIdx.y * blockDim.y;
  27. int offset = x + y * blockDim.x * gridDim.x;
  28. dst[offset] = tex2D(texRef2D, x, y);
  29. }
  30. int main(int argc, char **argv)
  31. {
  32. CUT_DEVICE_INIT(argc, argv); // 啟動 CUDA
  33. /// 1D 紋理內存
  34. cout << "1D texture" << endl;
  35. float *host1D = (float*)calloc(10, sizeof(float)); // 內存原數據
  36. float *hostRet1D = (float*)calloc(10, sizeof(float));// 內存保存返回數據
  37. float *dev1D, *devRet1D; // 顯存數據
  38. int i;
  39. cout << " host1D:" << endl;
  40. for(i = 0; i < 10; ++i) // 初始化內存原數據
  41. {
  42. host1D[i] = i * 2;
  43. cout << " " << host1D[i] << " ";
  44. }
  45. cutilSafeCall( cudaMalloc((void**)&dev1D, sizeof(float)*10)); // 申請顯存空間
  46. cutilSafeCall( cudaMalloc((void**)&devRet1D, sizeof(float)*10));
  47. cutilSafeCall( cudaMemcpy(dev1D, host1D, sizeof(float)*10, cudaMemcpyHostToDevice)); // 將內存數據拷貝入顯存
  48. cutilSafeCall( cudaBindTexture(NULL, texRef1D, dev1D, sizeof(float)*10)); // 將顯存數據和紋理綁定
  49. Texture1D<<<10, 1>>>(devRet1D, 10, 1); // 運行1D紋理操作函數
  50. cutilSafeCall( cudaMemcpy(hostRet1D, devRet1D, sizeof(float)*10, cudaMemcpyDeviceToHost)); // 將顯存數據拷貝入內存
  51. // 打印內存數據
  52. cout << endl << " hostRet1D:" << endl;
  53. for(i = 0; i < 10; ++i)
  54. cout << " " << hostRet1D[i] << " ";
  55. cutilSafeCall( cudaUnbindTexture(texRef1D)); // 解綁定
  56. cutilSafeCall( cudaFree(dev1D)); // 釋放顯存空間
  57. cutilSafeCall( cudaFree(devRet1D));
  58. free(host1D); // 釋放內存空間
  59. free(hostRet1D);
  60. /// 2D 紋理內存
  61. cout << endl << "2D texture" << endl;
  62. int width = 5, height = 3;
  63. float *host2D = (float*)calloc(width*height, sizeof(float)); // 內存原數據
  64. float *hostRet2D = (float*)calloc(width*height, sizeof(float)); // 內存返回數據
  65. cudaArray *cuArray; // CUDA數組
  66. float *devRet2D; // 顯存數據
  67. int row, col;
  68. cout << " host2D:" << endl;
  69. for(row = 0; row < height; ++row) // 初始化內存原數據
  70. {
  71. for(col = 0; col < width; ++col)
  72. {
  73. host2D[row*width + col] = row + col;
  74. cout << " " << host2D[row*width + col] << " ";
  75. }
  76. cout << endl;
  77. }
  78. cudaChannelFormatDesc channelDesc = cudaCreateChannelDesc<float>();
  79. cutilSafeCall( cudaMallocArray(&cuArray, &channelDesc, width, height)); // 申請顯存空間
  80. cutilSafeCall( cudaMalloc((void**) &devRet2D, sizeof(float)*width*height));
  81. cutilSafeCall( cudaBindTextureToArray(texRef2D, cuArray)); // 將顯存數據和紋理綁定
  82. cutilSafeCall( cudaMemcpyToArray(cuArray, 0, 0, host2D, sizeof(float)*width*height, cudaMemcpyHostToDevice)); // 將內存數據拷貝入CUDA數組
  83. dim3 threads(width, height);
  84. Texture2D<<<1, threads>>>(devRet2D, width, height); // 運行2D紋理操作函數
  85. cutilSafeCall( cudaMemcpy(hostRet2D, devRet2D, sizeof(float)*width*height, cudaMemcpyDeviceToHost)); // 將顯存數據拷貝入內存
  86. // 打印內存數據
  87. cout << " hostRet2D:" << endl;
  88. for(row = 0; row < height; ++row)
  89. {
  90. for(col = 0; col < width; ++col)
  91. cout << " " << hostRet2D[row*width + col] << " ";
  92. cout << endl;
  93. }
  94. cutilSafeCall( cudaUnbindTexture(texRef2D)); // 解綁定
  95. cutilSafeCall( cudaFreeArray(cuArray)); // 釋放顯存空間
  96. cutilSafeCall( cudaFree(devRet2D));
  97. free(host2D); // 釋放內存空間
  98. free(hostRet2D);
  99. CUT_EXIT(argc, argv); // 退出CUDA
  100. }
Copyright © Linux教程網 All Rights Reserved