【问题标题】:Multi-core programming in JavaJava中的多核编程
【发布时间】:2018-04-25 11:14:17
【问题描述】:

此程序按顺序获取输入文件,但所有任务使用单个内核并行执行。所有任务的执行时间都比顺序执行时间长。我想通过并行执行任务来减少使用多个内核的执行时间。我怎样才能做到这一点?如何在这个程序中使用多核?我想使用至少两个核心。

package TestParallel;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.crypto.Cipher;
import javax.crypto.CipherOutputStream;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;

/**
 *
 * @author Sohel Rana
 */
public class Executor {

    public void encrypt(File fname) throws Exception {
        System.out.println("Encryption Started : " + System.currentTimeMillis() + " File Name : " + fname);
        KeyGenerator keyGen = KeyGenerator.getInstance("AES");
        keyGen.init(256);  //using AES-256
        SecretKey key = keyGen.generateKey();  //generating key
        //  System.out.println("Key = " + bytesToHex(key.getEncoded()));
        Cipher aesCipher = Cipher.getInstance("AES");  //getting cipher for AES
        aesCipher.init(Cipher.ENCRYPT_MODE, key);  //initializing cipher for encryption with key

        //creating file output stream to write to file
        try (FileOutputStream fos = new FileOutputStream(fname + ".aes")) {
            //creating object output stream to write objects to file
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            oos.writeObject(key);  //saving key to file for use during decryption

            //creating file input stream to read contents for encryption
            try (FileInputStream fis = new FileInputStream(fname)) {
                //creating cipher output stream to write encrypted contents
                try (CipherOutputStream cos = new CipherOutputStream(fos, aesCipher)) {
                    int read;
                    byte buf[] = new byte[4096];
                    while ((read = fis.read(buf)) != -1) //reading from file
                    {
                        cos.write(buf, 0, read);  //encrypting and writing to file
                    }
                }
            }
            System.out.print("\nComplete Time = " + System.currentTimeMillis());
            System.out.println(" \tand file task complete :" + fname);
            //  fname.delete();
        }

    }

    public static void main(final String[] args) throws InterruptedException {
        // final ExecutorService pool = Executors.newFixedThreadPool(4);
        int cores = Runtime.getRuntime().availableProcessors();
        System.out.println("Available processor cores is " + cores);
        File file1 = new File("C:\\Users\\Sohel Rana\\Desktop\\test\\Khushnuma Official Video HD - Suyyash Rai & Kishwer Merchant_HD.mp4");
        File file2 = new File("C:\\Users\\Sohel Rana\\Desktop\\test\\EK MULAQAT - Sonali Cable HD.mp4");
        File file3 = new File("C:\\Users\\Sohel Rana\\Desktop\\test\\Java Cryptography Tutorials 1 AES Encryption and Decryption using Java.mp4");
        File file4 = new File("C:\\Users\\Sohel Rana\\Desktop\\test\\01. Nath Nath.MP4");

        Executor ex = new Executor();
        final ExecutorService executor = Executors.newFixedThreadPool(cores);
        long startTime = System.currentTimeMillis();
        for (File f : new File[]{file1, file2, file3, file4}) {
            startTime = System.currentTimeMillis();
            executor.execute(() -> {
                try {
                    ex.encrypt(f);
                    //System.out.println(f);
                } catch (Exception ex1) {
                    Logger.getLogger(Executor.class.getName()).log(Level.SEVERE, null, ex1);

                }
            });
        }

        executor.shutdown();

        if (executor.awaitTermination(1, TimeUnit.DAYS)) {
        } else {
            executor.shutdownNow();
        }
        long endTime = System.currentTimeMillis();

        System.out.println("\nParalle Execution Time : " + (endTime - startTime)
                + " milliseconds.");

    }
}

【问题讨论】:

  • 你的代码有什么问题?
  • 首先取决于你的硬件,这段代码是为哪个硬件编译的?该硬件是否至少有 2 个内核?
  • 你的意思是多线程。只需创建一个新线程
  • 我的代码在单核上运行良好。我想使用两个内核快速运行。我可以从 cpu 获得最大响应。这意味着当运行代码时,cpu 性能将是 100%。怎么能这样?
  • 分析您的代码以查看等待发生的位置...您在每个工作线程使用非常大的工作单元 - 即整个 mp4 文件,而每个工作人员通过读取 4kB 严重依赖 I/O当时......这是非常健谈的 I/O 访问,我的猜测(但在行动之前测量)是所有线程都花费大量时间等待 I/O。尝试当时读取 40kB 或 400kB,看看它会如何改变时间。您可以使用Executors.workStealingPool(cores),但要获得好处,您的工作项必须比整个文件小得多(可能是缓冲区的大小)。

标签: java parallel-processing aes executorservice multicore


【解决方案1】:

这里有一个将 InputStream 处理为 OutputStream 的情况。为此,可以使用 java nio 管道 I/O用两个线程完成。这样可以节省读写阻塞。

for 循环后的executor.shutdown(); 似乎为时过早。

其他都还好。

也许您的问题旨在利用 JVM 中的物理内核。最后我知道,Linux 在这一点上比 Windows 更好,但我很可能会犯错。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-10
    • 1970-01-01
    • 2010-10-10
    • 2021-12-14
    • 1970-01-01
    • 1970-01-01
    • 2011-03-05
    相关资源
    最近更新 更多