【发布时间】:2013-09-09 18:00:34
【问题描述】:
我一直在研究 C/C++ 中的散列,并尝试在 Linux 中复制 md5sum 命令。分析源码后,似乎md5sum依赖于md5库的md5_stream。我已经将 md5.h 库中的 md5_stream 函数近似为下面的代码,它运行时间约为 13-14 秒。我尝试直接调用 md5_stream 函数并得到〜13-14秒。 md5sum 在 4 秒内运行。 GNU 人做了什么来提高代码的速度?
CoreUtils 源代码中提供了 md5.h/md5.c 代码。
#include <QtCore/QCoreApplication>
#include <QtCore/QDebug>
#include <iostream>
#include <iomanip>
#include <fstream>
#include "md5.h"
#define BLOCKSIZE 32784
int main()
{
FILE *fpinput, *fpoutput;
if ((fpinput = fopen("/dev/sdb", "rb")) == 0) {
throw std::runtime_error("input file doesn't exist");
}
struct md5_ctx ctx;
size_t sum;
char *buffer = (char*)malloc (BLOCKSIZE + 72);
unsigned char *resblock = (unsigned char*)malloc (16);
if (!buffer)
return 1;
md5_init_ctx (&ctx);
size_t n;
sum = 0;
while (!ferror(fpinput) && !feof(fpinput)) {
n = fread (buffer + sum, 1, BLOCKSIZE - sum, fpinput);
if (n == 0){
break;
}
sum += n;
if (sum == BLOCKSIZE) {
md5_process_block (buffer, BLOCKSIZE, &ctx);
sum = 0;
}
}
if (n == 0 && ferror (fpinput)) {
free (buffer);
return 1;
}
/* Process any remaining bytes. */
if (sum > 0){
md5_process_bytes (buffer, sum, &ctx);
}
/* Construct result in desired memory. */
md5_finish_ctx (&ctx, resblock);
free (buffer);
for (int x = 0; x < 16; ++x){
std::cout << std::setfill('0') << std::setw(2) << std::hex << static_cast<uint16_t>(resblock[x]);
std::cout << " ";
}
std::cout << std::endl;
free(resblock);
return 0;
}
编辑:Fedora 19 64 位中的默认 mkspec 问题。
【问题讨论】:
-
当你构建你的代码时,你是在调试模式下构建的吗?您正在使用哪些优化级别?
-
是gnuutils...源码有,可以自己看。
-
Tim:目前我正在 Qt 中构建。默认情况下,Qt 构建环境添加 -O2 构建标志。我在发布模式下编译和测试,所以调试库和钩子不应该干扰。 MarcB:如果我查看 md5sum 源代码,我显然知道它是 GNUUtils。我正在寻找有关他们如何或在何处优化构建的见解。
-
您已经有了源代码,请查看 makefile 以确定使用了哪些编译器选项。
-
Fedora x64 和默认的 Qt 安装使用了错误的 mkspec 文件并且没有使用它应该使用的优化标志。 linux g++ (-O) 与 linux-64 g++(-O2/-O3)。我删除了通用的 linux mkspec,并建立了一个指向正确 linux-64 mkspec 的符号链接。一切都很好,并且优化得当。
标签: c++ performance md5 md5sum