1

我直奔主题。我有这个代码:

while (inputLength > 0)
{
    if (mode == MODE_AES_ENCRYPT)
        aesni_ecb_encrypt(ctx, input + shift, 16, output + shift);
    else if (mode == MODE_AES_DECRYPT)
        aesni_ecb_decrypt(ctx, input + shift, 16, output + shift);

    shift += 16;
    inputLength -= 16;
}

它对输入中的一个 16 字节块执行 AES-ECB 加密,并将结果存储在输出中。参数ctx是一个包含轮数和加密子密钥的结构。

AES-ECB 加密理论上可以并行化,所以我尝试对代码进行多线程处理,如下所示:

typedef struct
{
    AES_Context* Ctx;

    unsigned char* input;
    unsigned char* output;

    _Bool done;
} threadInfos;

unsigned long WINAPI ThreadFunc(threadInfos* data)
{
    aes_ecb_encrypt(data->Ctx, data->input, data->output);

    data->done = 1;
}

while (inputLength > 0) 
{
    threadInfos info1; info1.done = 0; info1.Ctx = ctx;
    threadInfos info2; info2.done = 0; info2.Ctx = ctx;
    threadInfos info3; info3.done = 0; info3.Ctx = ctx;
    threadInfos info4; info4.done = 0; info4.Ctx = ctx;

    info1.input = (input + shift); info1.output = (output + shift);
    info2.input = (input + shift + 16); info2.output = (output + shift + 16);
    info3.input = (input + shift + 32); info3.output = (output + shift + 32);
    info4.input = (input + shift + 48); info4.output = (output + shift + 48);

    CreateThread(NULL, 0, ThreadFunc, &info1, 0, NULL);
    CreateThread(NULL, 0, ThreadFunc, &info2, 0, NULL);
    CreateThread(NULL, 0, ThreadFunc, &info3, 0, NULL);
    CreateThread(NULL, 0, ThreadFunc, &info4, 0, NULL);

    while (info1.done == 0 || info2.done == 0 || info3.done == 0 || info4.done == 0)
        ;

    shift += 64;
    inputLength -= 64;
}

以下是速度方面的结果:

AES-ECB 单线程与 AES-ECB 4 线程

输出是相同的,这意味着我的多线程似乎正在工作,但是,它的效率非常低,因为它慢了 1000 倍......

这是我的问题。我怎样才能在 4 或 8 个线程上多线程加密 - 取决于 CPU 功能 - 但以这样一种方式,它更快,而不是 1000 倍慢?

4

1 回答 1

2

问题是您正在创建一个线程来执行 AES 算法的一个块,然后再次销毁它。正如您注意到的那样,速度要慢 1000 倍。你所有的时间都花在创建和销毁线程上。

您需要做的是在开始时创建一次线程,然后让它们每个都作为所有块的一部分工作。例如,线程 0 使用块 % 4 == 0 执行所有块,线程 1 使用块 % 4 == 1 执行所有块,依此类推。

注意:_Bool done;不是线程安全的。在例如 ARM 上,您的等待循环可能永远不会完成。

于 2018-06-12T10:29:58.610 回答