Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 顺序密钥的并发生成_C++_String_Concurrency_Sequential - Fatal编程技术网

C++ 顺序密钥的并发生成

C++ 顺序密钥的并发生成,c++,string,concurrency,sequential,C++,String,Concurrency,Sequential,我正在做一个项目,在一个非常紧密的循环中生成大量的连续文本字符串。我的应用程序在程序的其他部分大量使用SIMD指令集扩展,如SSE和MMX,但密钥生成器是普通C++。 我的密钥生成器的工作方式是我有一个keyGenerator类,它保存一个存储当前密钥的字符数组。要获取下一个键,有一个名为“incrementKey”的函数,该函数将字符串视为一个数字,向字符串中添加一个,并在必要时携带 现在的问题是,keygen有点瓶颈。速度很快,但如果速度快一点就好了。最大的问题之一是,当我生成一组要使用SS

我正在做一个项目,在一个非常紧密的循环中生成大量的连续文本字符串。我的应用程序在程序的其他部分大量使用SIMD指令集扩展,如SSE和MMX,但密钥生成器是普通C++。 我的密钥生成器的工作方式是我有一个keyGenerator类,它保存一个存储当前密钥的字符数组。要获取下一个键,有一个名为“incrementKey”的函数,该函数将字符串视为一个数字,向字符串中添加一个,并在必要时携带

现在的问题是,keygen有点瓶颈。速度很快,但如果速度快一点就好了。最大的问题之一是,当我生成一组要使用SSE2代码处理的顺序键时,我必须将整个键集存储在一个数组中,这意味着我必须依次生成12个字符串并将其复制到一个数组中,如下所示:

char* keys[12];
for(int i = 0; i < 12; i++)
{
    keys[i] = new char[16];
    strcpy(keys[i], keygen++);
}
char*键[12];
对于(int i=0;i<12;i++)
{
键[i]=新字符[16];
strcpy(key[i],keygen++);
}
那么,如何高效地按顺序生成这些纯文本字符串呢?我需要一些想法来推动这一进程。并发性会很好;正如我现在的代码所示,每个连续的键都依赖于前一个键,这意味着在当前键完全生成之前,处理器无法开始处理下一个键

以下是与密钥生成器相关的代码:

KeyGenerator.h

class keyGenerator
{

public:

    keyGenerator(unsigned long long location, characterSet* charset)
            : location(location), charset(charset)
    {           
        for(int i = 0; i < 16; i++)
            key[i] = 0;

        charsetStr = charset->getCharsetStr();
        integerToKey();
    }

    ~keyGenerator()
    {
    }

    inline void incrementKey()
    {
        register size_t keyLength = strlen(key);

        for(register char* place = key; place; place++)
        {
            if(*place == charset->maxChar)
            {
                // Overflow, reset char at place
                *place = charset->minChar;

                if(!*(place+1))
                {
                    // Carry, no space, insert char
                    *(place+1) = charset->minChar;
                    ++keyLength;

                    break;
                }
                else
                {
                    continue;
                }
            }
            else
            {
                // Space available, increment char at place
                if(*place == charset->charSecEnd[0]) *place = charset->charSecBegin[0];
                else if(*place == charset->charSecEnd[1]) *place = charset->charSecBegin[1];

                (*place)++;

                break;
            }
        }
    }

    inline char* operator++() // Pre-increment
    {
            incrementKey();
            return key;
    }

    inline char* operator++(int) // Post-increment
    {
            memcpy(postIncrementRetval, key, 16);
            incrementKey();

            return postIncrementRetval;
    }

    void integerToKey()
    {
        register unsigned long long num = location;

        if(!num)
        {
            key[0] = charsetStr[0];
        }
        else
        {
            num++;

            while(num)
            {
                num--;
                unsigned int remainder = num % charset->length;
                num /= charset->length;

                key[strlen(key)] = charsetStr[remainder];
            }
        }
    }

    inline unsigned long long keyToInteger()
    {
        // TODO
        return 0;
    }

    inline char* getKey()
    {
        return key;
    }

private:

    unsigned long long location;

    characterSet* charset;
    std::string charsetStr;

    char key[16];

    // We need a place to store the key for the post increment operation.
    char postIncrementRetval[16];
};
struct characterSet
{
    characterSet()
    {
    }

    characterSet(unsigned int len, int min, int max, int charsec0, int charsec1, int charsec2, int charsec3)
    {
        init(length, min, max, charsec0, charsec1, charsec2, charsec3);
    }

    void init(unsigned int len, int min, int max, int charsec0, int charsec1, int charsec2, int charsec3)
    {
        length = len;
        minChar = min;
        maxChar = max;

        charSecEnd[0] = charsec0;
        charSecBegin[0] = charsec1;
        charSecEnd[1] = charsec2;
        charSecBegin[1] = charsec3;
    }

    std::string getCharsetStr()
    {
        std::string retval;

        for(int chr = minChar; chr != maxChar; chr++)
        {
            for(int i = 0; i < 2; i++) if(chr == charSecEnd[i]) chr = charSecBegin[i];
            retval += chr;
        }

        return retval;
    }

    int minChar, maxChar;

    // charSec = character set section
    int charSecEnd[2], charSecBegin[2];

    unsigned int length;
};
类密钥生成器
{
公众:
keyGenerator(无符号长位置,字符集*字符集)
:位置(location)、字符集(charset)
{           
对于(int i=0;i<16;i++)
键[i]=0;
charsetStr=charset->getCharsetStr();
integerToKey();
}
~keyGenerator()
{
}
内联void incrementKey()
{
寄存器大小\u t keyLength=strlen(键);
for(register char*place=key;place;place++)
{
if(*place==charset->maxChar)
{
//溢出,在指定位置重置字符
*place=charset->minChar;
如果(!*(位置+1))
{
//进位,无空格,插入字符
*(位置+1)=字符集->最小字符;
++键长;
打破
}
其他的
{
继续;
}
}
其他的
{
//可用空间,在位置处增加字符数
如果(*place==charset->charSecEnd[0])*place=charset->charSecBegin[0];
否则,如果(*place==charset->charSecEnd[1])*place=charset->charSecBegin[1];
(*位置)++;
打破
}
}
}
内联字符*运算符+++()//预增量
{
递增键();
返回键;
}
内联字符*运算符++(int)//后增量
{
memcpy(增量后,键,16);
递增键();
返回增量后的tVAL;
}
void integerToKey()
{
寄存器无符号长数值=位置;
如果(!num)
{
键[0]=字符集TR[0];
}
其他的
{
num++;
while(num)
{
num--;
无符号整数余数=num%charset->length;
num/=字符集->长度;
键[strlen(键)]=charsetStr[余数];
}
}
}
内联无符号长keyToInteger()
{
//待办事项
返回0;
}
内联字符*getKey()
{
返回键;
}
私人:
无符号长位置;
字符集*字符集;
std::string charsetStr;
字符键[16];
//我们需要一个地方来存储增量后操作的密钥。
char postIncrementRetval[16];
};
字符集.h

class keyGenerator
{

public:

    keyGenerator(unsigned long long location, characterSet* charset)
            : location(location), charset(charset)
    {           
        for(int i = 0; i < 16; i++)
            key[i] = 0;

        charsetStr = charset->getCharsetStr();
        integerToKey();
    }

    ~keyGenerator()
    {
    }

    inline void incrementKey()
    {
        register size_t keyLength = strlen(key);

        for(register char* place = key; place; place++)
        {
            if(*place == charset->maxChar)
            {
                // Overflow, reset char at place
                *place = charset->minChar;

                if(!*(place+1))
                {
                    // Carry, no space, insert char
                    *(place+1) = charset->minChar;
                    ++keyLength;

                    break;
                }
                else
                {
                    continue;
                }
            }
            else
            {
                // Space available, increment char at place
                if(*place == charset->charSecEnd[0]) *place = charset->charSecBegin[0];
                else if(*place == charset->charSecEnd[1]) *place = charset->charSecBegin[1];

                (*place)++;

                break;
            }
        }
    }

    inline char* operator++() // Pre-increment
    {
            incrementKey();
            return key;
    }

    inline char* operator++(int) // Post-increment
    {
            memcpy(postIncrementRetval, key, 16);
            incrementKey();

            return postIncrementRetval;
    }

    void integerToKey()
    {
        register unsigned long long num = location;

        if(!num)
        {
            key[0] = charsetStr[0];
        }
        else
        {
            num++;

            while(num)
            {
                num--;
                unsigned int remainder = num % charset->length;
                num /= charset->length;

                key[strlen(key)] = charsetStr[remainder];
            }
        }
    }

    inline unsigned long long keyToInteger()
    {
        // TODO
        return 0;
    }

    inline char* getKey()
    {
        return key;
    }

private:

    unsigned long long location;

    characterSet* charset;
    std::string charsetStr;

    char key[16];

    // We need a place to store the key for the post increment operation.
    char postIncrementRetval[16];
};
struct characterSet
{
    characterSet()
    {
    }

    characterSet(unsigned int len, int min, int max, int charsec0, int charsec1, int charsec2, int charsec3)
    {
        init(length, min, max, charsec0, charsec1, charsec2, charsec3);
    }

    void init(unsigned int len, int min, int max, int charsec0, int charsec1, int charsec2, int charsec3)
    {
        length = len;
        minChar = min;
        maxChar = max;

        charSecEnd[0] = charsec0;
        charSecBegin[0] = charsec1;
        charSecEnd[1] = charsec2;
        charSecBegin[1] = charsec3;
    }

    std::string getCharsetStr()
    {
        std::string retval;

        for(int chr = minChar; chr != maxChar; chr++)
        {
            for(int i = 0; i < 2; i++) if(chr == charSecEnd[i]) chr = charSecBegin[i];
            retval += chr;
        }

        return retval;
    }

    int minChar, maxChar;

    // charSec = character set section
    int charSecEnd[2], charSecBegin[2];

    unsigned int length;
};
struct字符集
{
字符集()
{
}
字符集(无符号整数len、整数min、整数max、整数charsec0、整数charsec1、整数charsec2、整数charsec3)
{
初始值(长度、最小值、最大值、charsec0、charsec1、charsec2、charsec3);
}
void init(无符号整数len、整数min、整数max、整数charsec0、整数charsec1、整数charsec2、整数charsec3)
{
长度=长度;
minChar=min;
maxChar=max;
charSecEnd[0]=charsec0;
charSecBegin[0]=charsec1;
charSecEnd[1]=charsec2;
charSecBegin[1]=charsec3;
}
std::string getCharsetStr()
{
std::字符串检索;
for(int-chr=minChar;chr!=maxChar;chr++)
{
对于(inti=0;i<2;i++)如果(chr==charSecEnd[i]),chr=charSecBegin[i];
retval+=chr;
}
返回返回;
}
int minChar,maxChar;
//charSec=字符集部分
int charSecEnd[2],charSecBegin[2];
无符号整数长度;
};

好吧。。就性能而言,所有新的/strcpy/strmp对您的伤害可能比您的keygen更大

每次将内存分配到一个更大的池中,然后使用其中的指针

使用keygen,您应该避免坚持使用单个密钥的泄漏抽象,而是一次生成最佳数量的密钥。可能是更大的倍数


在某些时间间隔内,您实际上可以使用SSE/MMX生成键,至少在字符串对齐且可被SSE/MMX字长整除时是这样。您还可以尝试用0填充它,如果字符串不可用,则将其移开。如果一次只生成16个,那么这可能并不真正值得付出努力。

好吧。。就性能而言,所有新的/strcpy/strmp对您的伤害可能比您的keygen更大

每次将内存分配到一个更大的池中,然后使用其中的指针

使用keygen,您应该避免坚持单个密钥的泄漏抽象