{"id":243,"date":"2021-02-10T23:22:15","date_gmt":"2021-02-10T14:22:15","guid":{"rendered":"https:\/\/osmanthus.work\/?p=243"},"modified":"2021-04-01T06:11:41","modified_gmt":"2021-03-31T21:11:41","slug":"a-little-experiment-for-cpu-vs-gpu-using-cuda","status":"publish","type":"post","link":"https:\/\/osmanthus.work\/?p=243","title":{"rendered":"A little experiment for CPU vs GPU using CUDA"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">1. Introduction<\/h2>\n\n\n\n<p> I am a begineer of GPGPU. For performance comparison of CPU and GPU I did a little experiment using CUDA Toolkit.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">2. Prerequities<\/h2>\n\n\n\n<p>GPU: GeForce GTX 1060 6GB *<br>CPU: AMD Ryzen 7 3700X 8-Core Processor<br>OS: CentOS7.7<br>CUDA: CUDA11.2<br>Programing Language: C language<br>* I bought this GPU according to [1]<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">3. Installing CUDA<\/h2>\n\n\n\n<p>(1) Install CUDA11.2<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>wget https:\/\/developer.download.nvidia.com\/compute\/cuda\/11.2.0\/local_installers\/cuda-repo-rhel7-11-2-local-11.2.0_460.27.04-1.x86_64.rpm\nsudo rpm -i cuda-repo-rhel7-11-2-local-11.2.0_460.27.04-1.x86_64.rpm\nsudo yum clean all\nsudo yum -y install nvidia-driver-latest-dkms cuda\nsudo yum -y install cuda-drivers\n<\/code><\/pre>\n\n\n\n<p>(2) Check CUDA is installed or not<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>nvcc --version<\/code><\/pre>\n\n\n\n<p>(3) Check GPU is active or not<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>nvidia-smi<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">4. Build and Run program<\/h2>\n\n\n\n<h2 class=\"wp-block-heading\">4.1 Program using CPU<\/h2>\n\n\n\n<p>(1) Create the following source &#8220;calculate_cpu.c&#8221;. This program transpose two vectors to one vectors generating an element from two elements corresponding to source vectors in each element of vector.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#include &lt;stdio.h&gt;\n#include &lt;stdlib.h&gt;\n#include &lt;time.h&gt;\n#include &lt;math.h&gt;\n\nvoid vec_func(float *out, float *a, float *b, long long n) {\n    for(int i = 0; i &lt; n; i++){\n        out&#91;i] = log1p(expf((-1) * sqrt((log1p(abs(10 * sin(a&#91;i]) * cos(a&#91;i])))) + (log1p(abs(10 * sin(b&#91;i]) * cos(b&#91;i])))))));\n    }\n}\nint main(int argc, char *argv&#91;]){\n    float *a, *b, *out;\n    clock_t start, end;\n    long long N = atoll(argv&#91;1]);\n\n    \/\/ Allocate memory\n    a = (float*)malloc(sizeof(float) * N);\n    b = (float*)malloc(sizeof(float) * N);\n    out = (float*)malloc(sizeof(float) * N);\n    \n    \/\/ Initialize array\n    for(int i = 0; i &lt; N; i++){\n        a&#91;i] = (rand() \/ (float)RAND_MAX); b&#91;i] = (rand() \/ (float)RAND_MAX); out&#91;i] = 0.0f;\n    }\n    \n    \/\/ start\n    start = clock();\n\n    \/\/ Executing kernel\n    vec_func(out, a, b, N);\n\n    \/\/ end\n    end = clock();\n    printf(\"%f\\n\", ((double)(end - start)) \/ CLOCKS_PER_SEC );\n    \n    if(argc &gt; 2){\n        for(int i = 0; i &lt; N; i++){\n            printf(\"a:%f v:%f out:%f\\n\", a&#91;i], b&#91;i], out&#91;i]);\n        }\n    }\n}<\/code><\/pre>\n\n\n\n<p>(2) Build and Run. In my setup, the elapsed time during vec_func function execution is 51.52sec<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>gcc -std=c99 -lm .\/calculate_cpu.c -o .\/calculate_cpu\n.\/calculate_cpu 500000000<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">4.2 Program using GPU<\/h2>\n\n\n\n<p>(1) Create the following source &#8220;calculate_gpu.cu&#8221;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#include &lt;stdio.h&gt;\n#include &lt;stdlib.h&gt;\n#include &lt;cuda.h&gt;\n#include &lt;time.h&gt;\n#include &lt;math.h&gt;\n#include &lt;cuda_runtime.h&gt;\n\n__global__ void vec_func(float *out, float *a, float *b, long long n) {\n    int i = (blockIdx.x * blockDim.x) + threadIdx.x;\n    out&#91;i] = log1p(expf((-1) * sqrt((log1p(abs(10 * sin(a&#91;i]) * cos(a&#91;i])))) + (log1p(abs(10 * sin(b&#91;i]) * cos(b&#91;i])))))));\n}\n\nint main(int argc, char *argv&#91;]){\n    float *a, *b, *out;\n    float *d_a, *d_b, *d_out;\n    cudaEvent_t start, stop;\n    cudaEventCreate(&amp;start);\n    cudaEventCreate(&amp;stop);\n    long long N = atoll(argv&#91;1]);\n\n    \/\/ Allocate memory\n    a = (float*)malloc(sizeof(float) * N);\n    b = (float*)malloc(sizeof(float) * N);\n    out = (float*)malloc(sizeof(float) * N);\n    \n    \/\/ Initialize array\n    for(int i = 0; i &lt; N; i++){\n        a&#91;i] = (rand() \/ (float)RAND_MAX); b&#91;i] = (rand() \/ (float)RAND_MAX); out&#91;i] = 0.0f;\n    }\n    \n    \/\/ Allocate device memory\n    cudaMalloc((void**)&amp;d_a, sizeof(float) * N);\n    cudaMalloc((void**)&amp;d_b, sizeof(float) * N);\n    cudaMalloc((void**)&amp;d_out, sizeof(float) * N);\n    \n    \/\/ Transfer data from host to device memory\n    cudaMemcpy(d_a, a, sizeof(float) * N, cudaMemcpyHostToDevice);\n    cudaMemcpy(d_b, b, sizeof(float) * N, cudaMemcpyHostToDevice);\n\n    \/\/ start\n    cudaEventRecord(start);\n    \n    \/\/ Calculation in GPU\n    \/\/ Launch (N \/ 1024) blocks with 1024 threads per block with kernel&lt;&lt;&lt;N,M&gt;&gt;&gt;(\u2026);\n    vec_func&lt;&lt;&lt;N \/ 1024, 1024&gt;&gt;&gt;(d_out, d_a, d_b, N);\n    \n    \/\/ end\n    cudaEventRecord(stop);\n    cudaEventSynchronize(stop);\n    \n    \/\/ elapsed time\n    float milliseconds = 0;\n    cudaEventElapsedTime(&amp;milliseconds, start, stop);\n\n    \/\/ post process\n    cudaEventDestroy(start);\n    cudaEventDestroy(stop);\n\n    printf(\"vec_func: %f milli sec\\n\", milliseconds );\n    \n    \/\/ Transfer data back to host memory\n    cudaMemcpy(out, d_out, sizeof(float) * N, cudaMemcpyDeviceToHost);\n    if(argc &gt; 2){\n        for(int i = 0; i &lt; N; i++){\n            printf(\"a:%f v:%f out:%f\\n\", a&#91;i], b&#91;i], out&#91;i]);\n        }\n    }\n    \n    \/\/ Deallocate device memory\n    cudaFree(d_a);\n    cudaFree(d_b);\n    cudaFree(d_out);\n    \n    \/\/ Deallocate host memory\n    free(a);\n    free(b);\n    free(out);\n}<\/code><\/pre>\n\n\n\n<p>(2) Build and Run. In my setup, the elapsed time during vec_func function execution is 0.049sec<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>nvcc .\/calculate_gpu.cu -o .\/calculate_gpu\n.\/calculate_gpu 500000000<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">5. References<\/h2>\n\n\n\n<p>[1] CUDA-Enabled GeForce and TITAN Products<br><a href=\"https:\/\/developer.nvidia.com\/cuda-gpus\">https:\/\/developer.nvidia.com\/cuda-gpus<\/a><\/p>\n\n\n\n<p>[2] NVIDIA CUDA Installation Guide for Linux<br><a href=\"https:\/\/docs.nvidia.com\/cuda\/cuda-installation-guide-linux\/index.html#axzz4VX488ASJ\">https:\/\/docs.nvidia.com\/cuda\/cuda-installation-guide-linux\/index.html#axzz4VX488ASJ<\/a><\/p>\n\n\n\n<p>[3] CUDA C\/C++ Basics Supercomputing 2011 Tutorial<br><a href=\"https:\/\/www.nvidia.com\/docs\/IO\/116711\/sc11-cuda-c-basics.pdf\">https:\/\/www.nvidia.com\/docs\/IO\/116711\/sc11-cuda-c-basics.pdf<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>1. Introduction I am a begineer of GPGPU. For performance comparison of CPU and GPU I did a little experiment using CUDA Toolkit. 2. Prerequities GPU: GeForce GTX 1060 6GB *CPU: AMD Ryzen 7 3700X 8-Core ProcessorOS: CentOS7.7CUDA: CUDA11.2Programing Language: C language* I bought this GPU according to [1] 3. Installing CUDA (1) Install CUDA11.2 [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[10],"tags":[],"class_list":["post-243","post","type-post","status-publish","format-standard","hentry","category-programming","entry"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/osmanthus.work\/index.php?rest_route=\/wp\/v2\/posts\/243","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/osmanthus.work\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/osmanthus.work\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/osmanthus.work\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/osmanthus.work\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=243"}],"version-history":[{"count":8,"href":"https:\/\/osmanthus.work\/index.php?rest_route=\/wp\/v2\/posts\/243\/revisions"}],"predecessor-version":[{"id":392,"href":"https:\/\/osmanthus.work\/index.php?rest_route=\/wp\/v2\/posts\/243\/revisions\/392"}],"wp:attachment":[{"href":"https:\/\/osmanthus.work\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=243"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/osmanthus.work\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=243"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/osmanthus.work\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=243"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}