是否有类似 memset 的函数可以在 Visual Studio 中设置整数值? [英] Is there a memset-like function which can set integer value in visual studio?

查看:97
本文介绍了是否有类似 memset 的函数可以在 Visual Studio 中设置整数值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

1、可惜memset(void* dst, int value, size_t size) 很多人第一次使用这个函数的时候就糊弄了!第二个参数int value"应该是uchar value"来描述里面的真实操作.别误会,我问的是类似memset的功能!

1, It is a pity that memset(void* dst, int value, size_t size) fools a lot of people when they first use this function! 2nd parameter "int value" should be "uchar value" to describe the real operation inside. Don't misunderstand me, I am asking a memset-like function!

2,我知道有一些 C++ 糖果函数,比如 std::fill_n(my_array, array_length, constant_value);甚至是 OS X 中的纯 c 函数: memset_pattern4(grid, &pattern, sizeof grid);在一个完美的线程中提到 为什么 memset() 不正确地初始化 int?.

2, I know there are some c++ candy function like std::fill_n(my_array, array_length, constant_value); even a pure c function in OS X: memset_pattern4(grid, &pattern, sizeof grid); mentioned in a perfect thread Why is memset() incorrectly initializing int?.

那么,visual studio 的运行库中有没有类似memset_pattern4()这样的c函数?

So, is there a similar c function in runtime library of visual studio like memset_pattern4()?

3,有人问我为什么不使用 for 循环按整数设置整数.这是我的答案:至少在 x86 中设置大主干(10K?)内存时,memset 会获得更好的性能.

3, for somebody asked why i wouldn't use a for-loop to set integer by integer. here is my answer: memset turns to a better performance when setting big trunk(10K?) of memory at least in x86.

http://www.gamedev.net/topic/472631-performance-of-memset/page-2 提供了更多讨论,但没有得出结论(我怀疑会有).

http://www.gamedev.net/topic/472631-performance-of-memset/page-2 gives more discussion, although without a conclusion(I doubt there will be).

4、该函数可用于通过避免无用的斐波那契累积来简化计数排序.原文:

4, said function can be used to simplify counting sort by avoiding useless Fibonacci accumulation. Original:

for (int i = 0; i < SRC_ARRY_SIZE; i++)
    counter_arry[src_arry[i]]++; 

for (int i = SRC_LOW_BOUND; i < SRC_HI_BOUND; i++)//forward fabnacci??
    counter_arry[i+1] += counter_arry[i];

for (int i = 0; i < SRC_ARRY_SIZE; i++) 
{   
    value = src_arry[i];
    map = --counter_arry[value];//then counter down!
    temp[map] = value;
}

预期:

for (int i = 0; i < SRC_ARRY_SIZE; i++)
    counter_arry[src_arry[i]]++; 

for (int i = SRC_LOW_BOUND; i < SRC_HI_BOUND+1; i++)//forward fabnacci??
{           
    memset_4(cur_ptr,i, counter_arry[i]);
    cur_ptr += counter_arry[i];
}

感谢您的好评和回复!

推荐答案

这里是 memset_pattern4() 的一个实现,您可能会觉得它很有用.跟达尔文的SSE汇编语言版没什么区别,只是接口一样.

Here's an implementation of memset_pattern4() that you might find useful. It's nothing like Darwin's SSE assembly language version, except that it has the same interface.

#include <string.h>
#include <stdint.h>

/*

A portable implementation of the Darwin memset_patternX() family of functions:

These are analogous to memset(), except that they fill memory with a replicated
pattern either 4, 8, or 16 bytes long.  b points to a buffer of size len bytes
which is to be filled.  The second parameter points to the pattern.  If the
buffer length is not an even multiple of the pattern length, the last instance
of the pattern will be truncated.  Neither the buffer nor the pattern pointer
need be aligned.

*/

/*
alignment utility macros stolen from Linux
see https://lkml.org/lkml/2006/11/25/2 for a discussion of why typeof() is used
*/

#if !_MSC_VER

       #define __ALIGN_KERNEL(x, a)            __ALIGN_KERNEL_MASK(x, (typeof(x))(a) - 1)
       #define __ALIGN_KERNEL_MASK(x, mask)    (((x) + (mask)) & ~(mask))

       #define ALIGN(x, a)             __ALIGN_KERNEL((x), (a))
       #define __ALIGN_MASK(x, mask)   __ALIGN_KERNEL_MASK((x), (mask))
       #define PTR_ALIGN(p, a)         ((typeof(p))ALIGN((uintptr_t)(p), (a)))
       #define IS_ALIGNED(x, a)        (((x) & ((typeof(x))(a) - 1)) == 0)

       #define IS_PTR_ALIGNED(p, a)      (IS_ALIGNED((uintptr_t)(p), (a)))
#else
       /* MS friendly versions */

       /* taken from the DDK's fltKernel.h header */
       #define IS_ALIGNED(_pointer, _alignment)                        \
                     ((((uintptr_t) (_pointer)) & ((_alignment) - 1)) == 0)

       #define ROUND_TO_SIZE(_length, _alignment)                      \
                           ((((uintptr_t)(_length)) + ((_alignment)-1)) & ~(uintptr_t) ((_alignment) - 1))

       #define __ALIGN_KERNEL(x, a)    ROUND_TO_SIZE( (x), (a))
       #define ALIGN(x, a)             __ALIGN_KERNEL((x), (a))
       #define PTR_ALIGN(p, a)         ALIGN((p), (a))

       #define IS_PTR_ALIGNED(p, a)      (IS_ALIGNED((uintptr_t)(p), (a)))
#endif



void nx_memset_pattern4(void *b, const void *pattern4, size_t len)
{
       enum { pattern_len = 4 };

       unsigned char* dst = (unsigned char*) b;
       unsigned const char* src = (unsigned const char*) pattern4;

       if (IS_PTR_ALIGNED( dst, pattern_len) && IS_PTR_ALIGNED( src, pattern_len)) {
              /* handle aligned moves */
              uint32_t val = *((uint32_t*)src);
              uint32_t* word_dst = (uint32_t*) dst;

              size_t word_count = len / pattern_len;
              dst += word_count * pattern_len;
              len -= word_count * pattern_len;

              for (; word_count != 0; --word_count) {
                     *word_dst++ = val;
              }
       }
       else {
              while (pattern_len <= len) {
                     memcpy(dst, src, pattern_len);
                     dst += pattern_len;
                     len -= pattern_len;
              }
       }

       memcpy( dst, src, len);
}

这篇关于是否有类似 memset 的函数可以在 Visual Studio 中设置整数值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆