我会直截了当地说。 我有这段代码:
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;
}
以下是速度方面的结果:
输出是相同的,这意味着我的多线程似乎正在工作,但是,它效率非常低,因为它慢了1000倍......
这是我的问题。我怎么能在4或8个线程上多线程加密 - 取决于CPU的能力 - 但是这样的速度更快,而不是慢1000倍?
答案 0 :(得分:2)
问题是您正在创建一个线程来执行AES算法的一个块然后再次销毁它。你注意到它慢了1000倍。你所有的时间都花在创造和销毁线程上。
您需要做的是在开始时创建一次线程,然后让每个线程都成为所有块的一部分。例如,让线程0执行块%4 == 0的所有块,线程1执行块%4 == 1的所有块,依此类推。
注意:_Bool done;
不是线程安全的。在例如ARM等待循环可能永远不会完成。