English 中文(简体)
如何检查记忆栏中所有 by是否为零
原标题:How to check whether all bytes in a memory block are zero
  • 时间:2011-08-04 08:19:29
  •  标签:
  • c++

我有一组固定规模的记忆,即100个字塔,在另一边,所有固定长度相同,所以记忆犹如上。

<element1(100 bytes)><element2(100 bytes)><element3(100 bytes)>...

在某些情况下,我需要确定某个要素是否全部由零敲碎打确定,因为这具有特别的意义(我没有说这是一个好的想法,但这就是我所处的情况)。

问题是,我如何有效地这样做。 此外,还有这样做的简单职能。 by到零时,我可以使用 me子或zer子,但我不知道检查零的功能。

当时,我正在使用一个检查通道。

char *elementStart = memoryBlock + elementNr*fixedElementSize;
bool special = true;
for ( size_t curByteNr=0; curByteNr<fixedElementSize; ++curByteNr )
{
  special &= (*(elementStart+curByteNr)) == 0;
}

当然,我可以一劳永逸地打着一个大字或一些其他更合适的大字,检查几个字。 我猜想,这样做会非常有效,但我要知道,是否有职能从我那里承担这一负担。

建议的职能:

  • !memcmp (compareBlock, myBlock, fixedElementSize)
最佳回答

明显的便携式高效率方法是:

char testblock [fixedElementSize];
memset (testblock, 0, sizeof testblock);

if (!memcmp (testblock, memoryBlock + elementNr*fixedElementSize, fixedElementSize)
   // block is all zero
else  // a byte is non-zero

图书馆职能memcmp(>>,大多数实施都将使用最大、最有效率的单位规模,大部分比较都是这样。

提高效率,在操作时间不设置<条码>检测/编码>:

static const char testblock [100];

By definition, static variables are automatically initialized to zero unless there is an initializer.

问题回答

也许你可能实际上不必分配零价值阵列,否则会使用大鼠:

static int memvcmp(void *memory, unsigned char val, unsigned int size)
{
    unsigned char *mm = (unsigned char*)memory;
    return (*mm == val) && memcmp(mm, mm + 1, size - 1) == 0;
}

影响力标准并不说记忆重叠区域。

我不能相信没有人这样做。 a 一种解决办法实际上像C++, 并且是分行,以打破别的条款:

#include <algorithm> // std::all_of
#include <cstddef>   // std::size_t

// You might only need this
bool
memory_is_all_zeroes(unsigned char const* const begin,
                     std::size_t          const bytes)
{
    return std::all_of( begin, begin + bytes,
                        [](unsigned char const byte) { return byte == 0; } );
}

// but here s this as a bonus
template<typename T_Element, std::size_t T_count>
bool
array_is_all_zeroes( T_Element const (& array)[T_count] )
{
    auto const begin = reinterpret_cast<unsigned char const*>(array);
    auto const bytes = T_count * sizeof(T_Element);

    return memory_is_all_zeroes(begin, bytes);
}

int
main()
{
    int const blah[1000]{0};

    return !array_is_all_zeroes(blah);
}

这可能不符合一些人关于效率的假设(即假设,直至描述),但我认为,有效的和辅助性的守则在很大程度上有利于它。

AFAIK没有自动功能检查记忆。

您可使用“加速”,无需“=”

char *elementStart = memoryBlock + elementNr*fixedElementSize;
char special = 0;
for ( size_t curByteNr=0; curByteNr<fixedElementSize; ++curByteNr )
{
  special |= (*(elementStart+curByteNr));
}

而且,你可以长期使用,更快

char *elementStart = memoryBlock + elementNr*fixedElementSize;
long special = 0;
for ( size_t curByteNr=0; curByteNr<fixedElementSize; curByteNr += sizeof(long) )
{
   special |= *(long*)(elementStart+curByteNr);
}

www.un.org/Depts/DGACM/index_spanish.htm WARNING:没有测试上述代码。 请首先对其进行测试,使经营者的规模和投放者能够奏效。

I have tested some solutions proposed here and checked memcmp source code which is not optimized for the OP needs since it has an additional requirement to perform sorting, leading it to compare unsigned char one by one.

在下文中,我提议优化功能check_memory_zeroed,这些功能在最大配对面上进行大部分检查,使之便于使用。 我将这一功能与在座所提议的其他解决办法相比较。 进行了时间测量并印制了成果。

这表明,拟议的解决办法比挂图可移动的高效率方法<>差不多好两倍,不需要再制造一个阵列,比沙尔比较或海夫转移阵列多六倍,而后者则可以避免援助团与围墙之间的重叠。

我也测试了我的解决方案,但没有对以下文字加以调整:check_memory_zeroed_bigestint_not_ line,而且令人惊讶的是,它表现得更好。 如果有人解释,他会受到欢迎。

1Gb表上载有功能和性能测试的代码(拟议的优化功能是背心一:核对:零):

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
#include <assert.h>
#include <time.h>

#define BIG_TAB_SIZE 1000000000

typedef intmax_t biggestint;

int check_memory_zeroed (void* ptr, size_t size)
{
    if (ptr == NULL) return -1;
    int bis = sizeof(biggestint);
    char* pc = (char*) ptr;
    biggestint* pbi0 = (biggestint*) pc;
    if ((size_t) pc % bis) /* is aligned ? */
        pbi0 = (biggestint*) (pc + (bis - ((size_t) pc % bis))); /* minimal pointer larger than ptr but aligned */
    assert ((size_t) pbi0 % bis == 0); /* check that pbi0 is aligned */
    for (char* p = pc; p < (char*) pbi0; p++)
        if(*p) return 0; /* check beginning of non aligned array */
    biggestint* pbi = pbi0;
    biggestint* pbiUpper = ((biggestint*) (pc + size)) - 1;
    for (;pbi <= pbiUpper; pbi++)
        if(*pbi) return 0; /* check with the biggest int available most of the array : its aligned part */
    for (char* p = (char*) pbi; p < pc + size; p++)
        if(*p) return 0; /* check end of non aligned array */
    return 1;
}

int check_memory_zeroed_bigestint_not_aligned (void* ptr, size_t size)
{
    if (ptr == NULL) return -1;
    biggestint* pbi = (biggestint*) ptr;
    biggestint* pbiUpper = ((biggestint*) (((char*) ptr) + size)) - 1;
    for (;pbi <= pbiUpper; pbi++)
        if(*pbi) return 0; /* check with the biggest int available most of the array, but without aligning it */
    for (char* p = (char*) pbi; p < ((char*) ptr) + size; p++)
        if(*p) return 0; /* check end of non aligned array */
    return 1;
}

int check_memory_zeroed_by_char (void* ptr, size_t size)
{
    if (ptr == NULL) return -1;
    for (char* p = (char*) ptr; p < ((char*) ptr) + size; p++)
        if(*p) return 0;
    return 1;
}

/* variant of wallyk solution */
int check_memory_zeroed_by_memcmp_and_testblock (void* ptr, size_t size)
{
    void* testblock = malloc(size);
    if (ptr == NULL || testblock == NULL) return -1;
    memset (testblock, 0, sizeof(testblock));
    int res = ! memcmp (testblock, ptr, size);
    free (testblock);
    return res;
}

/* variant of mihaif solution */
int check_memory_zeroed_by_memcmp_with_shifted_array (void* ptr, size_t size)
{
    if (ptr == NULL) return -1;
    char* pc = (char*) ptr;
    return (*pc) || memcmp(pc, pc + 1, size - 1);
}

int test() {
    /* check_memory_zeroed (void* ptr, size_t size) */
    char tab[16];
    for (int i = 0; i < 8; i++)
        for (int j = 0; j < 8; j++) {
            for (int k = 0; k < 16; k++) tab[k] = (k >= i && k < 16 - j) ? 0 : 100 + k;
            assert(check_memory_zeroed(tab + i, 16 - j - i));
            if (i > 0) assert(tab[i-1] == 100 + i - 1);
            if (j > 0) assert(tab[16 - j] == 100 + 16 - j);
            for (int k = i; k < 16 - j; k++) {
                tab[k] = 200+k;
                assert(check_memory_zeroed(tab + i, 16 - j - i) == 0);
                tab[k] = 0;
            }
        }
    char* bigtab = malloc(BIG_TAB_SIZE);
    clock_t t = clock();
    printf ("Comparison of different solutions execution time for checking an array has all its values null
");
    assert(check_memory_zeroed(bigtab, BIG_TAB_SIZE) != -1);
    t = clock() - t;
    printf ("check_memory_zeroed optimized : %f seconds
",((float)t)/CLOCKS_PER_SEC);
    assert(check_memory_zeroed_bigestint_not_aligned(bigtab, BIG_TAB_SIZE) != -1);
    t = clock() - t;
    printf ("check_memory_zeroed_bigestint_not_aligned : %f seconds
",((float)t)/CLOCKS_PER_SEC);
    assert(check_memory_zeroed_by_char(bigtab, BIG_TAB_SIZE) != -1);
    t = clock() - t;
    printf ("check_memory_zeroed_by_char : %f seconds
",((float)t)/CLOCKS_PER_SEC);
    assert(check_memory_zeroed_by_memcmp_and_testblock(bigtab, BIG_TAB_SIZE) != -1);
    t = clock() - t;
    printf ("check_memory_zeroed_by_memcmp_and_testblock by wallyk : %f seconds
",((float)t)/CLOCKS_PER_SEC);
    assert(check_memory_zeroed_by_memcmp_with_shifted_array(bigtab, BIG_TAB_SIZE) != -1);
    t = clock() - t;
    printf ("check_memory_zeroed_by_memcmp_with_shifted_array by mihaif : %f seconds
",((float)t)/CLOCKS_PER_SEC);
    free (bigtab);

    return 0;
}

int main(void) {
    printf("Size of intmax_t = %lu
", sizeof(intmax_t));
    test();
    return 0;
}

比较不同解决方案执行时间核对阵列的结果,其所有价值都是无效的:

  • Size of intmax_t = 8
  • check_memory_zeroed optimized : 0.331238 seconds
  • check_memory_zeroed_bigestint_not_aligned : 0.260504 seconds
  • check_memory_zeroed_by_char : 1.958392 seconds
  • check_memory_zeroed_by_memcmp_and_testblock by wallyk : 0.503189 seconds
  • check_memory_zeroed_by_memcmp_with_shifted_array by mihaif : 2.012257 seconds

不可能同时检查所有100名tes。 因此,你(或任何公共事业职能)在任何情况下都必须通过数据加以检索。 但是,除了拥有大于1个等级的等级外,你还可以做一些更为优化的工作: 例如,一旦发现非零值,你就可使用<条码>。 我知道,时间的复杂性仍将是O(n)

我可以回顾一个标准图书馆职能,为你们做这项工作。 如果你不相信造成任何绩效问题,我只使用 lo,可以按建议用 in*取代char。

If you do have to optimize you could unroll the loop:

bool allZeroes(char* buffer)
{
    int* p = (int*)buffer;   // you better make sure your block starts on int boundary
    int acc = *p;
    acc |= *++p;
    acc |= *++p;
    ...
    acc |= *++p;    // as many times as needed

    return acc == 0;
}

You may need to add special handling for the end of buffer if it s size is not a multiple of sizeof(int), but it could be more efficient to allocate a slightly larger block with some padding bytes set to 0.

If your blocks are large you could treat them as a sequence of smaller blocks and loop over them, using the code above for each small block.

我很想知道这一解决办法如何与<代码>std:upper_french(begin,end,0)和>memcmp进行比较。

EDIT

Did a quick check how a home-grown implementation compares with memcmp, used VS2010 for that.

In short:

1) in debug mode home-grown can be twice as fast as memcmp

(2) 释放时,完全优化的症状在从零开始的区块上edge。 随着零填充的序言的长度的增加,它开始消失,但有些how魔力却几乎像本土一样迅速,只有10%的放慢。

So depending on your data patterns and need/desire to optimize you could get some extra performance from rolling out your own method, but memcmp is a rather reasonable solution.

如果你可以使用,则将守则和结果放在阴道上。

The following will iterate through the memory of a structure. Only disadvantage is that it does a bytewise check.

#include <iostream>

struct Data { int i; bool b; };

template<typename T>
bool IsAllZero(T const& data)
{
    auto pStart = reinterpret_cast<const char*>(&data);
    for (auto pData = pStart; pData < pStart+sizeof(T); ++pData)
    {
        if (*pData)
            return false;
    }

    return true;
}

int main()
{
    Data data1;// = {0}; // will most probably have some content
    Data data2 = {0}; // all zeroes

    std::cout << "data1: " << IsAllZero(data1) << "
data2: " << IsEmptyStruct(data2);

    return 0;
};

What about using long int and binary or operator.

unsigned long long int *start, *current, *end, value = 0;
// set start,end
for(current = start; current!=end; current++) {
value |= *current;
}
bool AllZeros = !value;

Well if you just want to decide whether a single element is all 0s you can create a 100byte element with all 1s. Now when you want to check whether an element is all 0s just binary AND (&) the content of the element and the element you created(all 1s). now if the result of binary AND is zero the element you checked had all 0s otherwise it was not all 0s

the creation of a 100 byte element with all 1s seems costly but if you have a large number of elements to check then its actually better

you can create the 100 byte element with all 1s as void *elem; elem=malloc(100); now set all bits to 1(use ~(elem&0))





相关问题
Undefined reference

I m getting this linker error. I know a way around it, but it s bugging me because another part of the project s linking fine and it s designed almost identically. First, I have namespace LCD. Then I ...

C++ Equivalent of Tidy

Is there an equivalent to tidy for HTML code for C++? I have searched on the internet, but I find nothing but C++ wrappers for tidy, etc... I think the keyword tidy is what has me hung up. I am ...

Template Classes in C++ ... a required skill set?

I m new to C++ and am wondering how much time I should invest in learning how to implement template classes. Are they widely used in industry, or is this something I should move through quickly?

Print possible strings created from a Number

Given a 10 digit Telephone Number, we have to print all possible strings created from that. The mapping of the numbers is the one as exactly on a phone s keypad. i.e. for 1,0-> No Letter for 2->...

typedef ing STL wstring

Why is it when i do the following i get errors when relating to with wchar_t? namespace Foo { typedef std::wstring String; } Now i declare all my strings as Foo::String through out the program, ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

Window iconification status via Xlib

Is it possible to check with the means of pure X11/Xlib only whether the given window is iconified/minimized, and, if it is, how?