【问题标题】:C crypt_r really 32 times slower than crypt?C crypt_r 真的比 crypt 慢 32 倍?
【发布时间】:2014-10-10 05:46:46
【问题描述】:

我正在做一个概念验证 decrypt bruteforcer,并且单线程版本在 i-7 860 cpu 的单核下以大约 190k 哈希/秒的速度运行良好。

我现在正在尝试制作这个程序的多线程版本(我第一次玩线程,所以我希望我在这里做错了)。

我第一次尝试直接使用 crypt,这速度很快,但由于线程正在竞争 crypt 函数,因此导致散列损坏。

在函数上使用互斥锁和解锁会有所帮助,但这会将程序的速度降低到仅比单线程版本高几个百分点。

然后我设法用谷歌搜索了 crypt_r,它被宣传为线程安全的。 修改了单线程版本以使用 crypt_r(单线程) 和多线程版本使用它而不是 crypt,当使用两个核心以 99.9% 的利用率时,单线程版本的性能下降到大约 3.6k h/s 和多线程版本的大约 7.7k h/s。

所以问题是,它应该这么慢吗?

【问题讨论】:

  • crypt_r 的实现是谁的? glibc? eglibc?
  • 一个既是线程安全又是可重入的函数(根据man page,请注意它们不是一回事)似乎会带来开销。
  • @Leeor 为什么?我看不出哈希函数不纯的任何原因..
  • 一个理智的实现会让不可重入函数只分配一个缓冲区并调用可重入的_r版本。它不应该很慢,因为最终它们都应该是完全相同的实现。这正是 glibc 所做的:code.metager.de/source/xref/gnu/glibc/crypt/crypt-entry.c
  • 可以对搜索空间进行分区吗?运行单独的进程不是更有意义吗?像SETI@Home这样的东西?线程很难!

标签: c multithreading performance des crypt


【解决方案1】:

问题是,我在执行 crypt_r 函数时调用的函数还包含用于初始化它所需的结构的代码。

解决方案是将初始化移出散列完成时调用的函数。

简化示例不正确方式:

for (int i = 0; i < 200000; i++)
{
    struct crypt_data data;
    data.initialized = 0;

    char* hash = crypt_r("password", "sa", &data);
    printf("%i %s", i, hash);
}

正确方法:

struct crypt_data data;
data.initialized = 0;

for (int i = 0; i < 200000; i++)
{
    char* hash = crypt_r("password", "sa", &data);
    printf("%i %s", i, hash);
}

【讨论】:

    猜你喜欢
    • 2011-07-16
    • 2019-03-07
    • 2013-01-10
    • 2021-04-12
    • 2014-01-23
    • 1970-01-01
    • 2015-09-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多