【问题标题】:Confusing results in benchmarking Java md5sum on different devices在不同设备上对 Java md5sum 进行基准测试的结果令人困惑
【发布时间】:2017-04-16 15:14:39
【问题描述】:

简短的问题:

为什么在 Java 中计算 5 MB 文件的 md5-sum 在 Raspberry Pi 上需要 84 秒,而在 Mac 上只需要 25 毫秒?

整个问题:

我需要编写一个 Java 程序,它计算一堆文件的 md5 或 sha-sum,这些文件的总大小约为 50 GB。

为此,我编写了一个简单的 Java 程序,它计算单个 5 MB 文件的校验和。这是Java程序:

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;

public class Main {

    public static final int BLOCKSIZE = 8*1024;

    public static void main(String[] args) throws FileNotFoundException, NoSuchAlgorithmException{
        String path = Main.class.getResource("file5M.img").getPath();
        File file = new File(path);
        FileInputStream fin = new FileInputStream(file);
        MessageDigest messageDigest = MessageDigest.getInstance("MD5");

        long fileSize = file.length();
        int length;
        long alreadyRead = 0;
        long startTime = System.currentTimeMillis();
        byte[] bytes = new byte[BLOCKSIZE];
        try {
            while (true) {
                int maxToRead = (int) (fileSize - alreadyRead < BLOCKSIZE ? fileSize - alreadyRead : BLOCKSIZE);

                if ((length = fin.read(bytes, 0, maxToRead)) < 0) break;
                messageDigest.update(bytes, 0, length);
                if ((alreadyRead += length) >= fileSize) break;
            }
        } catch (IOException ex){
            ex.printStackTrace();
        }
        byte[] md5 = messageDigest.digest();
        long stopTime = System.currentTimeMillis();
        long elapsedTime = stopTime - startTime;
        System.out.println("Time:\t" + elapsedTime + "\tRead:\t" + alreadyRead/1024/1024);
        System.out.println("MD5: " + Arrays.toString(md5));
    }
}

为了创建一个随机文件图像,我使用了这个 Linux 命令:

dd if=/dev/urandom of=file5M.txt bs=1M count=5

在不同的设备上执行程序,会导致混乱的结果:

 <table style="width:100%">
  <tr>
    <th>Time in ms</th>
    <th>Computer</th>
    <th>CPU</th>
    <th>RAM</th>
    <th>Harddrive</th>
    <th>Operating-System</th>
  </tr>
  <tr>
    <td>24</td>
    <td>MacBook Pro (13-inch, 2016)</td>
    <td>3.3 GHz Intel Core i7</td>
    <td>8 GB 2133 MHz LPDDR3</td>
    <td>APPLE SSD AP1024J</td>
    <td>MacOs Sierra</td>
  </tr>
  <tr>
    <td>45000</td>
    <td>Raspberry Pi Modell B</td>
    <td>0.7 GHz ARMv6 (32-bit)</td>
    <td>256 MB</td>
    <td>PRO microSD Card (SD Adapter)</td>
    <td>Arch Linux</td>
  </tr>
  <tr>
    <td>7600</td>
    <td>Odroid XU4</td>
    <td>Exynos5 Octa Cortex™-A15 1.6Ghz quad core and Cortex™-A7 quad core CPUs</td>
    <td>2Gbyte LPDDR3 RAM PoP</td>
    <td>Samsung PRO microSD Card (SD Adapter)</td>
    <td>Arch Linux for Odroid-XU3</td>
  </tr>
  <tr>
    <td>300</td>
    <td>VirtualBox on MacBook Pro</td>
    <td>1 Core with 0.7GHz (21% of MacCPU) no PAE/NX, no acceleration</td>
    <td>256MB of MacRAM PIIX3 with APIC</td>
    <td>Dynamic Allocated 8GB (VDI)</td>
    <td>Arch Linux 64-Bit</td>
  </tr>
</table>

那么为什么程序在 MacBook 上的执行速度如此之快,即使我限制了 VirtualBox 中的 CPU 和 RAM?

瓶颈在哪里?

我必须做些什么才能让程序在 Odroid-XU4 上以大约 300 毫秒的时间执行?

备注:

我不认为是 microSD 的 I/O,因为它读取整个文件的速度非常快,无需计算 md5sum。

将 odroid 上的 cpu 频率从 2Ghz 更改为 500MHz,将计算时间从 7 秒增加到 24 秒。

【问题讨论】:

  • 为什么你的 read-loop 看起来像这样?
  • @Kayaman 因为文件将通过套接字传输,在文件传输完成后没有 EOF。但我知道文件的大小。
  • 什么?因此,您显示的代码使用FileInputStream,但实际代码从套接字读取文件?为什么要显示你没有运行的代码?
  • 因为我描述的基准测试是用这段代码测量的。我不认为等待 EOF 会有所作为。不管你是对的,我本可以进一步简化代码。
  • 只是每次有人使用非标准的读取循环时,都会对整个代码产生怀疑,即使在这里不会有所作为。

标签: java performance raspberry-pi md5 odroid


【解决方案1】:

Raspberry Pi 的 RAM 频率比 MacBook 低得多。这可能就是为什么它甚至在 VirtualBox 中运行得更快的原因。因为当你读取一个文件时,它会存储在 RAM 中,即使速度非常快,你每次读取文件时都有 I/O 访问权限,并用 MD5 算法求和。

另外,如果你想提高性能,我建议你在程序中使用线程(在线程之间调度文件)。请注意,如果您的虚拟机上只有一个内核,那么线程将毫无用处。

【讨论】:

  • 听起来很合乎逻辑,但这个事实是否也适用于 odroid-XU4。我的意思是他的 7000 毫秒和 mac 上的 20 毫秒的差异是极端的。文件不应该轻松地放入 Ram 上的 2GB 内存中吗? Odroid 的 LPDDR3 RAM 真的那么烂吗?
  • 如您所见:hardkernel.com/main/products/… odroid 的频率约为 900MHz,远低于 macbook 的 2xxx
  • 好的不错的答案 :) 但是这看起来 Ordoid 的 RAM 比 mac 慢了大约 3 倍。但是为什么结果不是20ms*3左右呢?或者至少 0.5 秒?
  • 我不认为它是线性的,没那么简单,仅仅通过比较内存频率你无法预测它需要多少时间:)
  • 我明白你的意思。我们能以某种方式证明它真的是 ram 频率吗?我的意思是也许我可以在 Virtualbox 中模拟它,或者我们可以通过不同设备的 ram 频率来计算加速公式,这将证明你的理论......
猜你喜欢
  • 1970-01-01
  • 2014-08-10
  • 2011-02-01
  • 2017-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多