- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我制作了一个 OpenCL 程序并使用固定内存 (CL_MEM_ALLOC_HOST_PTR
) 来获得从设备到主机的更高传输速率。
传输速率按我的预期增加(使用 AMD APP Profiler 2.4 获得传输速率)。
问题是矩阵 4096 x 4096 (64 MB) 的传输速率高于 PCIe 带宽 (93703 GB/s)。
当我使用零复制缓冲区(CL_MEM_ALLOC_HOST_PTR + clEnqueueMapBuffer)时,它也发生了。
我搜索了一些信息,如果固定内存和零复制缓冲区具有高传输率,但它仍然受限于离散 GPU 的 PCIe 带宽。
那么,如果传输速率超过 PCIe 带宽(使用 PCIe 带宽 2.0 x 16)是否正常?
我的操作系统是 Windows 7 64 位。
我使用 AMD APP SDK 2.6 和独立 GPU AMD HD 6630M。
编辑:
这是代码:
#include <Windows.h>
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
#ifdef __APPLE__
#include <OpenCL/opencl.h>
#else
#include <CL/cl.h>
#endif
#define MAX_SOURCE_SIZE (0x100000)
cl_context context = NULL;
cl_command_queue queue = NULL;
cl_program program = NULL;
void MatrixMul(cl_mem d_A, cl_mem d_B, cl_mem d_C, int size)
{
cl_int err;
cl_kernel naive;
// Create Kernel Object Bound To Kernel Function
naive = clCreateKernel(program, "naiveAlgorithm", &err);
//Set size of global work item and work tem in each work goups
int globalsize = size;
int localsize;
if(globalsize >= 16)
{
localsize =16;
}else
{
localsize = globalsize;
}
size_t global_work_items [2] = {globalsize, globalsize};
size_t local_work_items [2] = {localsize, localsize};
// Setup Kernel Argument
err = clSetKernelArg(naive, 0, sizeof(cl_mem), (void *)&d_A);
err = clSetKernelArg(naive, 1, sizeof(cl_mem), (void *)&d_B);
err = clSetKernelArg(naive, 2, sizeof(cl_mem), (void *)&d_C);
err = clSetKernelArg(naive, 3, sizeof(cl_int), (void *)&size);
// Execute OpenCL kernel for Naive Algorithm
err = clEnqueueNDRangeKernel(queue, naive, 2, NULL, global_work_items, local_work_items, 0, NULL, NULL);
clFinish(queue);
//Release Kernel
err = clReleaseKernel(naive);
}
void Naive(cl_float* matrixA, cl_float* matrixB, cl_float* matrixC, int size)
{
int err;
// OpenCL device memory for matrices
cl_mem d_A;
cl_mem d_B;
cl_mem d_C;
// Allocate Device Memory For Input And Output
d_A = clCreateBuffer(context, CL_MEM_READ_ONLY , sizeof(cl_float)*size*size, 0, &err);
d_B = clCreateBuffer(context, CL_MEM_READ_ONLY , sizeof(cl_float)*size*size, 0, &err);
d_C = clCreateBuffer(context, CL_MEM_WRITE_ONLY|CL_MEM_ALLOC_HOST_PTR ,sizeof(cl_float)*size*size, 0,&err);
// Copy Host Memory To Memory Device
err = clEnqueueWriteBuffer(queue, d_A, CL_FALSE, 0, sizeof(cl_float)*size*size, matrixA, 0, NULL, NULL);
err = clEnqueueWriteBuffer(queue, d_B, CL_FALSE, 0, sizeof(cl_float)*size*size, matrixB, 0, NULL, NULL);
MatrixMul(d_A, d_B, d_C, size);
err = clEnqueueReadBuffer(queue, d_C, CL_TRUE, 0, sizeof(cl_float)*size*size, matrixC, 0, NULL, NULL);
err = clReleaseMemObject(d_A);
err = clReleaseMemObject(d_B);
err = clReleaseMemObject(d_C);
}
//Main Function
int main(int argc, char **argv)
{
//Size of matrix for Strassen Algorithm
cl_int size = 4096;
//Matrix for input and output
cl_float * matrixA;
cl_float * matrixB;
cl_float * matrixC;
//Allocate and init memory for the host
matrixA = (cl_float *) malloc(size*size*sizeof(cl_float));
matrixB = (cl_float *) malloc(size*size*sizeof(cl_float));
matrixC = (cl_float *) malloc(size*size*sizeof(cl_float));
//Fill matrix
fillMatrix(matrixA,size);
fillMatrix(matrixB,size);
//print input for matrix A and B
cout<<"Input for matrix A :"<<endl;
printMatrix(matrixA, size*size, size);
cout<<"Input for matrix B :"<<endl;
printMatrix(matrixB, size*size, size);
cl_int err; // error code
cl_platform_id* platforms;
cl_uint platformCount;
cl_device_id device;
int platformtype = 0; //if 0 using amd app sdk but if 1 using intel sdk
clGetPlatformIDs(0, NULL, &platformCount); //get number of platform
platforms = (cl_platform_id*) malloc(sizeof(cl_platform_id) * platformCount);
clGetPlatformIDs(platformCount, platforms, NULL); //get list of platform
clGetDeviceIDs (platforms [platformtype], CL_DEVICE_TYPE_GPU, 1, &device, NULL); //get list of devices
const cl_context_properties contextProperties [] =
{CL_CONTEXT_PLATFORM,
reinterpret_cast<cl_context_properties> (platforms [platformtype]),
0, 0
};
context = clCreateContext(contextProperties, 1, &device, NULL, NULL, &err);
![enter image description here][2]queue = clCreateCommandQueue(context, device, CL_QUEUE_PROFILING_ENABLE, &err);
//Load Kernel Source
FILE *fp;
const char fileName[] = "./MatMul_Kernel.cl";
size_t source_size;
char *source_str;
fp = fopen(fileName, "r");
if (!fp)
{
fprintf(stderr, "Failed to load kernel.\n");
exit(1);
}
source_str = (char *)malloc(MAX_SOURCE_SIZE);
source_size = fread(source_str, 1, MAX_SOURCE_SIZE, fp);
fclose(fp);
// Create Program Object
program = clCreateProgramWithSource(context, 1, (const char **) &source_str,(const size_t *),
&source_size, &err);
// Build Program
err = clBuildProgram(program, 1, &device, NULL, NULL, NULL);
Naive(matrixA, matrixB, matrixC, size);
//Cleanup all memory
err = clFlush(queue);
err = clFinish(queue);
err = clReleaseProgram(program);
err = clReleaseCommandQueue(queue);
err = clReleaseContext(context);
// Display result of matrix multiplication
cout<<"Output for matrix C :"<<endl;
printMatrix(matrixC, size*size, size);
cout<<endl;
free(matrixA);
free(matrixB);
free(matrixC);
free(source_str);
return 0;
}
__kernel void naiveAlgorithm(__global float *A, __global float *B, __global float *C, int size) {
int tx = get_global_id(0); //2D Thread IDx
int ty = get_global_id(1); //2D Thread IDy
float sum = 0;
//Calculate result of one element of Matrix C
for (int k = 0; k < size; k++) {
sum += A[ty*size+k] * B[k*size+tx];
}
C[ty*size+tx] = sum;
}
最佳答案
我看到您的输出数组实际上位于主机内存中,因为 CL_MEM_ALLOC_HOST_PTR
以下行中的标志:
d_C = clCreateBuffer(context, CL_MEM_WRITE_ONLY|CL_MEM_ALLOC_HOST_PTR ,sizeof(cl_float)*size*size, 0,&err);
clEnqueueMapBuffer
,然后以您认为合适的任何方式使用矩阵,然后是
clEnqueueUnmapMemObject
.由于 d_C 已经在主机内存中,因此不需要数组 matrixC。
clEnqueueReadBuffer
的文档。是否适用于固定内存。我还看到您正在检索每个操作的错误代码,但不检查这些错误代码,因此您的代码可能会默默地失败。
clEnqueueReadBuffer
所用时间的巨大差异以及传输数据所花费的时间,请注意,所有排队的操作不会立即分派(dispatch)到 GPU。延迟的来源之一是显卡的 Windows 显示驱动程序模型 (WDDM)。用于
clEnqueueReadBuffer
的 +-20 微秒听起来很适合这种延迟(我实际上已经看到了更长的延迟)。
关于OpenCL 传输速率超过 PCI-e 带宽,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20415347/
当操作系统枚举 PCI 总线时,它会从每个 PCI 设备收集信息。我的问题是,操作系统在哪里存储这些信息?每个操作系统在运行时是否在 RAM 中都有一个 64KB 的数组? 最佳答案 PCI 信息被存
我们正在做一个项目,它的性质有点像拼车,我读到了 PCI 合规性,我知道如果我们处理信用卡或付款,我们必须符合 PCI 合规性我有点模棱两可,我们是否存储我们的司机银行信息例如数据库中的帐号(加密),
我们过去从未传输、处理或存储信用卡信息,因为我们通过 PayPal 完成所有操作,因此我们从不需要符合 PCI 标准。 但是,我们正在推出一个新的在线商店,并通过无缝结账处理信用卡信息而不重定向到 P
我有一个 NIC 卡和一个 HDD,它们都连接在 Linux 机器的 PCIe 插槽上。理想情况下,我希望在不涉及 CPU 或最少涉及 CPU 的情况下将传入数据包传送到 HDD。是否可以像这样沿着
根据 PCI 标准,设备是根据供应商 ID、设备 ID 和总线编号来识别的。所有相同类型的设备都具有相同的供应商 ID 和设备 ID。如果我将两个这样的设备放在同一条总线上,比如总线 0。PCI 软件
我正在查看商家帐户,据我所知,存储送货地址符合 PCI 合规性,这是真的吗?此外,Recurly 的 API 似乎需要 SAQ C 或 SAQ D,我查看了一些示例问题: 配置标准是否包括对防火墙的要
我们进行的某些信用卡处理需要符合 PCI 标准。人们在其他商店是如何做到这一点的? 如何保护您的 SVN? 如何保护构建服务器的安全? 代码如何从开发人员迁移到生产环境? 最佳答案 不是为了转移其他答
我只是想知道如果您存储加密的信用卡号以进行定期计费,PCI 认证级别会是多少。 我计划每年交易量少于 20,000 笔,但我不确定存储的信用卡号码。 最佳答案 如果您确实(确实)需要存储卡号,那么您就
我正在查看商家帐户,据我所知,存储送货地址符合 PCI 合规性,这是真的吗?此外,Recurly 的 API 似乎需要 SAQ C 或 SAQ D,我查看了一些示例问题: 配置标准是否包括对防火墙的要
我知道 PCI 配置空间中的基地址寄存器 (BAR) 定义了 PCI 地址的起始位置,但是该区域的大小是如何确定的? 当然,这是硬件的一个属性,因为只有它知道它可以处理的地址空间有多远。但是,我似乎在
我正在做的是开发一款财务软件,并将其连接到符合 pci 标准的第三方信用卡公司。我们公司是一家加拿大公司。我们不符合 pci,也不打算符合 pci。但我们希望保存 PAN 的后 4 位数字,以帮助一线
我目前正在从事该项目,其功能之一是电子商务,因此我们的系统应负责用户信用卡信息和其他凭证信息的安全性。 我知道任何处理用户支付卡信息的网络服务都应遵循 PCI 合规性(支付卡信息数据安全标准)。作为前
我们需要为基于订阅/定期付款的 SaaS 应用程序存储信用卡的最后 4 位数字(以便让客户知道他们使用了哪张卡?)和到期日期(通知客户他们的卡即将到期)。 PCI DSS 中允许这两种数据存储吗?请引
我正在用 C# 编写一个程序来对许多 Windows XP 工作站执行硬件审核。 我需要确定哪些 PCI 设备是通过主板插槽连接的实际卡 - 而不是也使用 PCI 总线(内置于主板中)的板载设备。 我
在 Linux 中,有没有办法找出哪个 PCI 卡插入哪个 PCI 插槽? /sys/bus/pci/devices/包含许多不是卡的设备(网桥、CPU channel 等),我无法在设备目录中找到有
我们想使用银行 API 从我们的银行账户到用户的银行账户进行 SEPA 转账。为此,用户需要在表格中输入他的 IBAN 和 BIC。我们获取这些数据(受 SSL 保护)并使用银行 REST API 转
我以前从未处理过 PCI 合规性问题。我一直在阅读他们的文档,它说我需要保护信用卡号、到期日期和持卡人的姓名。永远不会存储安全代码。 在他们的文档中,它只是说保护。这是说我需要加密数据库中的这 3 列
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 2 年前。 Improve th
我正在做一个项目,我需要从用户空间通过 PCI BAR0 访问 FPGA 内存。 我以前在旧内核中所做的是打开位于 /sys/bus/pci/devices/my_device/ 中的名为 resou
如果我的 PCI 总线(没有 PCI-PCI 桥)有 3 个设备: spy 设备、发送方 PCI 设备和接收方设备(例如,从 PCI 到 CPU 的桥接器)。 发送方开始向接收方传输数据。 spy 设
我是一名优秀的程序员,十分优秀!