为什么GTX Titan上的Cublas比单线螺纹CPU代码慢
Why cublas on GTX Titan is slower than single threaded CPU code?
我正在我的GTX Titan上测试Nvidia Cublas库。我有以下代码:
#include "cublas.h"
#include <stdlib.h>
#include <conio.h>
#include <Windows.h>
#include <iostream>
#include <iomanip>
/* Vector size */
#define N (1024 * 1024 * 32)
/* Main */
int main(int argc, char** argv)
{
LARGE_INTEGER frequency;
LARGE_INTEGER t1, t2;
float* h_A;
float* h_B;
float* d_A = 0;
float* d_B = 0;
/* Initialize CUBLAS */
cublasInit();
/* Allocate host memory for the vectors */
h_A = (float*)malloc(N * sizeof(h_A[0]));
h_B = (float*)malloc(N * sizeof(h_B[0]));
/* Fill the vectors with test data */
for (int i = 0; i < N; i++)
{
h_A[i] = rand() / (float)RAND_MAX;
h_B[i] = rand() / (float)RAND_MAX;
}
QueryPerformanceFrequency(&frequency);
QueryPerformanceCounter(&t1);
/* Allocate device memory for the vectors */
cublasAlloc(N, sizeof(d_A[0]), (void**)&d_A);
cublasAlloc(N, sizeof(d_B[0]), (void**)&d_B);
/* Initialize the device matrices with the host vectors */
cublasSetVector(N, sizeof(h_A[0]), h_A, 1, d_A, 1);
cublasSetVector(N, sizeof(h_B[0]), h_B, 1, d_B, 1);
/* Performs operation using cublas */
float res = cublasSdot(N, d_A, 1, d_B, 1);
/* Memory clean up */
cublasFree(d_A);
cublasFree(d_B);
QueryPerformanceCounter(&t2);
double elapsedTime = (t2.QuadPart - t1.QuadPart) * 1000.0 / frequency.QuadPart;
std::cout << "GPU time = " << std::setprecision(16) << elapsedTime << std::endl;
std::cout << "GPU result = " << res << std::endl;
QueryPerformanceFrequency(&frequency);
QueryPerformanceCounter(&t1);
float sum = 0.;
for (int i = 0; i < N; i++) {
sum += h_A[i] * h_B[i];
}
QueryPerformanceCounter(&t2);
elapsedTime = (t2.QuadPart - t1.QuadPart) * 1000.0 / frequency.QuadPart;
std::cout << "CPU time = " << std::setprecision(16) << elapsedTime << std::endl;
std::cout << "CPU result = " << sum << std::endl;
free(h_A);
free(h_B);
/* Shutdown */
cublasShutdown();
getch();
return EXIT_SUCCESS;
}
运行代码时,我会得到以下结果:
GPU time = 164.7487009845991
GPU result = 8388851
CPU time = 45.22368030957917
CPU result = 7780599.5
为什么在GTX Titan上使用Cublas库是一个Xeon 2.4GHz Ivybridge Core上的计算慢的3倍?当我增加或减少矢量大小时,我会得到相同的结果:GPU比CPU慢。双精度不会改变它。
,因为点产品是仅使用每个向量元素一次的函数。这意味着将其发送到视频卡的时间比计算CPU上的所有内容要大得多,因为PCIEXPRESS比RAM慢得多。
我认为您应该阅读此内容:
http://blog.theincredibleholk.org/blog/2012/12/10/optimizing-dot-product/
有三个要点,我将简要评论:
-
gpu擅长隐藏带有大量计算的潜伏期(如果您可以在计算和数据传输之间平衡),则在这里访问了很多内存(带宽有限问题),并且没有足够的计算来隐藏潜伏期,实际上是杀死您的表演。
-
此外,仅读取一次缓存功能一次仅读取,而CPU非常擅长预测接下来的哪些数据。
-
加上您也将分配时间计时。
上面的所有列出了您刚刚发布的示例,其中CPU胜过像GPU这样的大量并行体系结构。
对此类问题的优化可能是:
- 尽可能多地将数据保存在设备上
- 让线程计算更多元素(因此隐藏潜伏期)
也:http://www.nvidia.com/object/nvidia_research_pub_001.html
相关文章:
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- 什么时候最好在子进程中使用 CPU 或 I/O 密集型代码 [ C++ ]
- TensorFlow CPU 和 CUDA 代码共享
- 为什么当从面向任何 CPU 的 C# 项目调用此代码时,此代码会引发 System.AccessViolationExc
- 维护/维持两个代码集的风险,一个用于 CPU,一个用于 GPU,需要执行非常相似的功能
- 从 C++11 代码中获取系统内存和 CPU 使用率
- C++代码只能针对特定的 CPU 体系结构进行编译.有没有办法将其编译为所有架构
- 任何可以在单个 CPU 指令中在 0 和 1 之间翻转位/整数/布尔值的可能代码
- 代码执行/CPU 速度每 2 秒减慢一次
- 为什么 OpenMP 在这个 fft 代码中停留在 10% 的 CPU 消耗?
- 为什么GTX Titan上的Cublas比单线螺纹CPU代码慢
- 测量C 代码的CPU周期
- 为什么Opencv GPU代码比CPU慢
- 在CPU上使用OpenCL将一个数组复制到另一个数组比C++代码慢得多
- 是否可以计算出有多少 CPU 和 RAM 使用代码块
- 如何计算C++代码段的 CPU 周期成本
- GPU 调用后,CPU 代码运行缓慢
- 可视化设置一个c++应用程序使用最大CPU使用率,在代码中
- gcc/C++:如果CPU负载很低,那么代码优化用处不大,这是真的
- 使用 CUDA 计算积分图像比 CPU 代码慢