-2

I wrote a program which constituted by several class,but the calculation is too slow(Program in bold), I hope get my java program running on GPU to speed up the computation,or is there another way to speed up the running speed,How do I change my code? Calculation of the program are as follows:

public class ComputeThreadPool {
  public static double[][] distance = new double[40][8];
  public static HashMap<String,Double> simMap = new HashMap<String,Double>();
static class WorkThread implements Runnable {
    private Map<String, Double> testWordTFMap;
    private Map<String, Double> trainWordTFMap;
    private Map<String, double[]> words;
    private String trainname;

    public WorkThread(Map<String, Double> map1, Map<String, Double> map2, Map<String, double[]> words,String trainname) {
        this.testWordTFMap = map1;
        this.trainWordTFMap = map2;
        this.words = words;
        this.trainname=trainname;
    }

    @Override
    public void run() {
         System.out.println(Thread.currentThread().getName()+" Start. Command = "+command);
        double mul = 0, testAbs = 0, trainAbs = 0;

        WordsSimilarity computeS = new WordsSimilarity();
        double wf = 0;
        Set<Map.Entry<String, Double>> testWordTFMapSet = testWordTFMap.entrySet();
        for (Iterator<Map.Entry<String, Double>> it = testWordTFMapSet.iterator(); it.hasNext(); ) {
            Map.Entry<String, Double> me = it.next();
            Set<Map.Entry<String, Double>> trainWordTFMapSet = trainWordTFMap.entrySet();
            ***for (Iterator<Map.Entry<String, Double>> it2 = trainWordTFMapSet.iterator(); it2.hasNext(); ) {
                Map.Entry<String, Double> me2 = it2.next();              
                    wf = computeS.similarity(me.getKey(), me2.getKey(), words);
                if (wf > 0.45)
                    mul += wf * me.getValue() * me2.getValue();
            }
        }***

        for (Iterator<Map.Entry<String, Double>> it3 = testWordTFMapSet.iterator(); it3.hasNext(); ) {
            Map.Entry<String, Double> me3 = it3.next();
            testAbs += me3.getValue() * me3.getValue();
        }
        testAbs = Math.sqrt(testAbs);
        Set<Map.Entry<String, Double>> trainWordTFMapSet = trainWordTFMap.entrySet();
        for (Iterator<Map.Entry<String, Double>> it4 = trainWordTFMapSet.iterator(); it4.hasNext(); ) {
            Map.Entry<String, Double> me4 = it4.next();
            trainAbs += me4.getValue() * me4.getValue();
        }

        trainAbs = Math.sqrt(trainAbs);
        simMap.put(trainname,mul / (testAbs * trainAbs));
        System.out.println(Thread.currentThread().getName() + " Start.     " );
        processCommand();
        System.out.println(Thread.currentThread().getName() + " End.");
    }
    private void processCommand() {
        try {
            Thread.sleep(5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

public static HashMap<String,Double> main(Map<String, Double> testWordTFMap,Map<String, TreeMap<String, Double>> trainFileNameWordTFMap,Map<String, double[]> words) {
    int num=0;
    ExecutorService executor = Executors.newFixedThreadPool(6);
    Set<Map.Entry<String,TreeMap<String,Double>>> trainFileNameWordTFMapSet = trainFileNameWordTFMap.entrySet();
    for(Iterator<Map.Entry<String,TreeMap<String,Double>>> it = trainFileNameWordTFMapSet.iterator(); it.hasNext();){
        Map.Entry<String, TreeMap<String,Double>> me = it.next();
        num=num++;
        Runnable worker = new WorkThread(testWordTFMap,me.getValue(),words,me.getKey());
        executor.execute(worker);
    }
    executor.shutdown();
    while (!executor.isTerminated()) {
    }
    System.out.println("Finished all threads");

    return simMap;
}

}

wf is calculated as follows:

    public static double similarity(String word1, String word2,Map<String, double[]> words) {

    double[] count1=words.get(word1);
    double[] count2=words.get(word2);
    double sum=0;
    double Abs1=0;
    double Abs2=0;
    if(count1 == null || count2 == null) {
        return 0;
    }
    for (int c = 0; c < count1.length; c++) {
        sum += count1[c] * count2[c];
        Abs1 += count1[c] * count1[c];
        Abs2 += count2[c] * count2[c];
    }
    return sum / (Abs1 * Abs2);

}                                                                                           
Amy
  • 43
  • 3
  • 2
    What is "too slow"? Have you done any profiling to identify which methods take the most time? We cannot tell you what to optimize without profiling data. – Jim Garrison Feb 29 '16 at 09:04
  • 1
    The GPU doesn't understand Java byte code. The better question is how to invoke logic on the GPU from a Java program. http://stackoverflow.com/questions/22866901/using-java-with-nvidia-gpus-cuda – Gimby Feb 29 '16 at 09:24
  • You shouldn't note that GPUs get their processing power from large vector operations. Data structures like Map are not supported even if Java could be run on a GPU. What you can do is run OpenCL via the JavaCL library http://opencv.org/platforms/opencl.html – Peter Lawrey Feb 29 '16 at 09:42
  • 2
    @PeterLawrey Wrong link, I guess. Some approaches are listed in the answer that Gimby linked to. However, for the given code snippet, there are dozens of ways of how the performance could be improved, even though the (likely) most important class, `WordsSimilarity`, is missing here. – Marco13 Feb 29 '16 at 09:49

1 Answers1

1

You would need to find an implementation of the JVM that runs on the GPU or a runtime environment/shell that targets the GPU in which you can run the standard JVM; but unless the JVM is built for the GPU you may or may not get performance gains.

However I would say, you should be able to find optimisations within the code first. Such as using enhanced for loops. Other than the compute word similarity there doesn't seem to much there that should be causing excessive run time.

Gavin
  • 1,725
  • 21
  • 34