我和一些朋友讨论了一段代码,我们讨论了在C中使用memset函数,如果我们初始化一个大小为N的数组,这个函数的Big-O表示法的顺序是什么?
来自在线文档:
cudaError_t cudaMemset (void * devPtr, int value, size_t count )
Run Code Online (Sandbox Code Playgroud)
使用常量字节值填充devPtr指向的内存区域的第一个计数字节.
参数:devPtr -指向设备存储器值-值设置每个字节指定的存储器计数-大小在字节设置
此描述似乎不正确:
int *dJunk;
cudaMalloc((void**)&dJunk, 32*(sizeof(int));
cudaMemset(dJunk, 0x12, 32);
Run Code Online (Sandbox Code Playgroud)
将所有32个整数设置为0x12,而不是0x12121212.(Int vs Byte)
描述讨论了设置字节.计数和值以字节为单位进行描述.通知计数的类型为size_t,值的类型为int.即将字节大小设置为int值.
编程指南中未提及cudaMemset().我必须假设我看到的行为是正确的,文档很糟糕.
那里有更好的文档来源吗?(在哪里?)
是否支持其他类型?即会float *dJunk;工作吗?其他?
我有这个代码
char * oldname = new char[strlen(name) + 1];
memcpy(oldname,name,strlen(name) + 1);
name = new char[strlen(oldname) + strlen(r.name) + 1];
memset(name, '\0', strlen(name));
strcat(name,oldname);
strcat(name," ");
strcat(name,r.name);
Run Code Online (Sandbox Code Playgroud)
我理解使用memcpy和memset是不行的,但我还没有完全理解如何在C++中使用它,最好没有std.
有人知道吗?谢谢.
我没有找到这个问题的确切答案,所以这是一个愚蠢的问题,或者只是显而易见的问题.我想知道它是否会产生未定义的行为.
我定义了一些结构类型:
typedef struct {
char string1[17];
char string2[33];
int someInt;
float someFloat;
} my_struct_t;
Run Code Online (Sandbox Code Playgroud)
我需要该结构的多个实例(就像你在struct数组中一样),但是在编译时对象的数量是未知的.
像这样初始化它是否正确?
my_struct_t *myStruct;
size_t noOfElements;
size_t completeSize;
int index;
/* ...code which sets the number of elements at runtime... */
completeSize = sizeof(my_struct_t) * noOfElements;
myStruct = malloc(completeSize);
memset(myStruct, 0, completeSize);
/* ...and then access it as if it were an array...*/
myStruct[index].someInt = 10; // index < noOfElements
Run Code Online (Sandbox Code Playgroud)
这样做安全吗?这memset()部分是我担心的.
似乎无法在任何地方找到答案,如何将数组memset到数组类型的最大值?我原以为memset(ZBUFFER,0xFFFF,size)ZBUFFER是一个16位整数数组.相反,我得到-1s.
此外,我们的想法是尽可能快地完成这项工作(这是一个需要初始化每一帧的zbuffer),所以如果有更好的方法(并且仍然快速或更快),请告诉我.
编辑:作为澄清,我需要一个签名的int数组.
我正在尝试尽可能小地构建一个应用程序,并且这样做是为了避免使用Win API调用而不是标准的C/C++调用来使用CRT.不幸的是,我仍然遇到一个链接器错误:
Error 2 error LNK2001: unresolved external symbol _memcpy
Run Code Online (Sandbox Code Playgroud)
我不会在我的代码中的任何地方调用memcpy,所以我假设其中一个Windows函数正在调用它.打开内部函数会给出一个未解析的符号_memset,我也没有使用它.根据我的理解,memcpy和memset都应包含在启用的内部函数中.由于我的代码太长而无法发布,以下是我的程序中的Win API调用:
我的问题:
我想知道如何在C中使用该memset()函数two dimensional array.
我不想面对该阵列中的任何垃圾问题.如何初始化此数组?
有人能解释我如何实现它吗?
我的CPU的规格说它应该为内存带来5.336GB/s的带宽.为了测试这个,我写了一个简单的程序,在一个大数组上运行memset(或memcpy)并报告时间.我在memset上显示3.8GB/s,在memcpy上显示1.9GB/s. http://en.wikipedia.org/wiki/Intel_Core_(microarchitecture)说我的Q9400应该达到5.336MB/s.怎么了?
我试过用赋值循环替换memset或memcpy.我已经google了一下,试图了解内存对齐情况.我尝试过不同的编译器标志.我花了很多时间在这上面尴尬.感谢您的任何帮助,您可以提供!
我正在使用Ubuntu 12.04和libc-dev版本2.15-0ubuntu10.5和内核3.8.0-37-generic
代码:
#include <stdio.h>
#include <time.h>
#include <string.h>
#include <stdlib.h>
#define numBytes ((long)(1024*1024*1024))
#define numTransfers ((long)(8))
int main(int argc,char**argv){
if(argc!=3){
printf("Usage: %s BLOCK_SIZE_IN_BYTES NUMBER_OF_BLOCKS_TO_TRANSFER\n",argv[0]);
return -1;
}
char*__restrict__ source=(char*)malloc(numBytes);
char*__restrict__ dest=(char*)malloc(numBytes);
struct timespec start,end;
long totalTimeMs;
int i;
clock_gettime(CLOCK_MONOTONIC_RAW,&start);
for(i=0;i<numTransfers;++i)
memset(source,0,numBytes);
clock_gettime(CLOCK_MONOTONIC_RAW,&end);
totalTimeMs=(end.tv_nsec-start.tv_nsec)*.000001+1000*(end.tv_sec-start.tv_sec);
printf("memset %ld bytes %ld times (%.2fGB total) in %ldms (%.3fGB/s). ",numBytes,numTransfers,numBytes/1024.0/1024/1024*numTransfers,totalTimeMs,numBytes/1024.0/1024/1024*1000*numTransfers/totalTimeMs);
clock_gettime(CLOCK_MONOTONIC_RAW,&start);
for(i=0;i<numTransfers;++i)
memcpy( dest, source, numBytes);
clock_gettime(CLOCK_MONOTONIC_RAW,&end);
totalTimeMs=(end.tv_nsec-start.tv_nsec)*.000001+1000*(end.tv_sec-start.tv_sec);
printf("memcpy %ld bytes %ld times (%.2fGB total) in %ldms (%.3fGB/s).\n",numBytes,numTransfers,numBytes/1024.0/1024/1024*numTransfers,totalTimeMs,numBytes/1024.0/1024/1024*1000*numTransfers/totalTimeMs);
free(source);
free(dest);
return …Run Code Online (Sandbox Code Playgroud) 我一直在测试一个OpenMP并行代码中的代码,memset并行运行会有什么好处吗?我正在观察一些意外的事情.
我的系统是一个单插槽Xeon E5-1620,它是一个Ivy Bridge处理器,有4个物理内核和8个超线程.我使用的是Ubuntu 14.04 LTS,Linux Kernel 3.13,GCC 4.9.0和EGLIBC 2.19.我编译gcc -fopenmp -O3 mem.c
当我在链接中运行代码时,它默认为八个线程并给出
Touch: 11830.448 MB/s
Rewrite: 18133.428 MB/s
Run Code Online (Sandbox Code Playgroud)
但是,当我绑定线程并将线程数设置为这样的物理核心数
export OMP_NUM_THREADS=4
export OMP_PROC_BIND=true
Run Code Online (Sandbox Code Playgroud)
我明白了
Touch: 22167.854 MB/s
Rewrite: 18291.134 MB/s
Run Code Online (Sandbox Code Playgroud)
触控率增加了一倍!绑定后运行几次总是比重写更快.我不明白这一点.绑定线程并将其设置为物理核心数后,为什么触摸比重写更快?为什么触控率翻倍?
这是我使用的代码,没有修改Hristo Iliev的答案.
#include <stdio.h>
#include <string.h>
#include <omp.h>
void zero(char *buf, size_t size)
{
size_t my_start, my_size;
if (omp_in_parallel())
{
int id = omp_get_thread_num();
int num = omp_get_num_threads();
my_start = (id*size)/num;
my_size = ((id+1)*size)/num - my_start;
}
else
{
my_start = 0;
my_size …Run Code Online (Sandbox Code Playgroud) 很偶然地在内核丛林中偶然发现了一些代码并且有点困惑。有两种实现kzalloc():在tools/virtio/linux/kernel.h 中,主要的在linux/slab.h 中。显然,在大多数情况下,使用第二个。但有时使用“virtio” kzalloc()。
“virtio”kzalloc()看起来像这样:
static inline void *kzalloc(size_t s, gfp_t gfp)
{
void *p = kmalloc(s, gfp);
memset(p, 0, s);
return p;
}
Run Code Online (Sandbox Code Playgroud)
我的困惑是kmalloc()在“tools”目录中使用的“fake”会返回 NULL 指针。此外,该memset()实现似乎不检查 NULL 指针,因此可能存在 NULL 指针取消引用。这是一个错误还是我错过了什么?