Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从EDU迁移到java.util.concurrent会两次降低性能_Java_Multithreading_Concurrency - Fatal编程技术网

从EDU迁移到java.util.concurrent会两次降低性能

从EDU迁移到java.util.concurrent会两次降低性能,java,multithreading,concurrency,Java,Multithreading,Concurrency,交叉柱 有一个电信应用服务器(基于JAIN SLEE)和运行在其中的应用程序。 应用程序正在接收来自网络的消息,对其进行处理并将响应发送回网络。 对于95%的呼叫,请求/响应延迟要求为250毫秒;对于99.999%的呼叫,请求/响应延迟要求为3000毫秒。 我们使用EDU.oswego.cs.dl.util.concurrent.ConcurrentHashMap,1个实例。对于一个调用(一个调用是多个消息),将调用以下方法: "put", "get", "get", "get", then i

交叉柱

有一个电信应用服务器(基于JAIN SLEE)和运行在其中的应用程序。
应用程序正在接收来自网络的消息,对其进行处理并将响应发送回网络。
对于95%的呼叫,请求/响应延迟要求为250毫秒;对于99.999%的呼叫,请求/响应延迟要求为3000毫秒。
我们使用EDU.oswego.cs.dl.util.concurrent.ConcurrentHashMap,1个实例。对于一个调用(一个调用是多个消息),将调用以下方法:

"put", "get", "get", "get", then in 180 seconds "remove".
有4个线程调用这些方法。
(注意:使用ConcurrentHashMap并不是唯一的活动。对于一条网络消息,还有许多其他活动:协议消息解析、查询数据库、将SDR写入文件、创建短期和长期对象。)

当我们从EDU.oswego.cs.dl.util.concurrent.ConcurrentHashMap移动到java.util.concurrent.ConcurrentHashMap时,我们看到性能从每秒1400次下降到800次。
每秒最后800次呼叫的第一个瓶颈是没有足够的延迟满足上述要求

这种性能下降会在具有以下CPU的主机上重现:

  • 2 CPU x四核AMD Opteron 2356 2312 MHz,共8个硬件线程,
  • 2 CPU x英特尔至强E5410 2.33 GHz,8 HW线程总数。
它不会在X5570 CPU(英特尔至强Nehalem X5570 2.93 GHz,总共16个硬件线程)上复制


有人面临过类似的问题吗?如何解决这些问题?

我想你用的是纳秒而不是毫秒。(比原来小一百万倍!)

使用ConcurrentHashMap只是延迟的一小部分

编辑:已使用100个任务将示例编辑为多线程

/*
Average operation time for a map of 10,000,000 was 48 ns
Average operation time for a map of 5,000,000 was 51 ns
Average operation time for a map of 2,500,000 was 48 ns
Average operation time for a map of 1,250,000 was 46 ns
Average operation time for a map of 625,000 was 45 ns
Average operation time for a map of 312,500 was 44 ns
Average operation time for a map of 156,200 was 38 ns
Average operation time for a map of 78,100 was 34 ns
Average operation time for a map of 39,000 was 35 ns
Average operation time for a map of 19,500 was 37 ns
 */
 public static void main(String... args) {
    ExecutorService es = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
    try {
        for (int size = 100000; size >= 100; size /= 2)
            test(es, size);
    } finally {
        es.shutdown();
    }
}

private static void test(ExecutorService es, final int size) {
    int tasks = 100;
    final ConcurrentHashMap<Integer, String> map = new ConcurrentHashMap<Integer, String>(tasks*size);
    List<Future> futures = new ArrayList<Future>();
    long start = System.nanoTime();
    for (int j = 0; j < tasks; j++) {
        final int offset = j * size;
        futures.add(es.submit(new Runnable() {
            public void run() {
                for (int i = 0; i < size; i++)
                    map.put(offset + i, "" + i);
                int total = 0;
                for (int j = 0; j < 10; j++)
                    for (int i = 0; i < size; i++)
                        total += map.get(offset + i).length();
                for (int i = 0; i < size; i++)
                    map.remove(offset + i);
            }
        }));
    }
    try {
        for (Future future : futures)
            future.get();
    } catch (Exception e) {
        throw new AssertionError(e);
    }
    long time = System.nanoTime() - start;
    System.out.printf("Average operation time for a map of %,d was %,d ns%n", size * tasks, time / tasks / 12 / size);
}
/*
10000000 map的平均操作时间为48纳秒
500万map的平均运行时间为51纳秒
对于2500000的map,平均操作时间为48 ns
1250000 map的平均运行时间为46纳秒
62.5万map的平均操作时间为45纳秒
312500 map的平均操作时间为44纳秒
156200 map的平均操作时间为38纳秒
78100 map的平均操作时间为34纳秒
39000 map的平均操作时间为35纳秒
19500年map的平均操作时间为37纳秒
*/
公共静态void main(字符串…参数){
ExecutorService es=Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
试一试{
用于(整数大小=100000;大小>=100;大小/=2)
试验(es、尺寸);
}最后{
es.shutdown();
}
}
专用静态无效测试(服务执行者,最终整数大小){
int任务=100;
最终ConcurrentHashMap=新ConcurrentHashMap(任务*大小);
列表期货=新的ArrayList();
长启动=System.nanoTime();
对于(int j=0;j
首先,您是否检查了哈希映射是否确实是罪魁祸首?假设您这样做了:有一个设计用于扩展到数百个处理器而不引入大量争用。它是由Cliff Click编写的,Cliff Click是原始热点编译器团队中的一位著名工程师。现在,我们正在将JDK扩展到具有数百个CPU的机器上。所以,我假设他知道在散列映射实现中他在做什么。有关此哈希映射的更多信息,请参见这些。

您是否尝试更改ConcurrentHashMap中的ConcurrentLevel?尝试一些较低的值,如8,尝试一些较大的值。请记住,ConcurrentHashMap的性能和并发性取决于HashCode函数的质量

是的,它-java.util.ConcurrentHashMap与edu.oswego.cs.dl具有相同的来源(来自edu.oswego的Doug Lee,但它完全被他改写了,所以它可以更好地扩展


我认为您可以查看javolution快速地图。它可能更适合于实时应用程序。

很有趣,但您是否需要转到
java.util.concurrent
?即使这两个库有着相同的起源,它们也已经疏远了,而oswego库很可能从那时起就已经融入了性能改进。这是一个真正的问题吗?这更像是一个观察,然后是一个邀请,邀请大家“分享经验”。(尽管这是一个有趣的观察!)@skaffman由于许可证问题,我们不得不从EDU.oswego.cs.dl.util.concurrent迁移。顺便说一句,这些库的起源并不相同:EDU基于经典同步;java.util.concurrent基于CompareAndSwap指令。分析应用程序时,您看到了什么?@Neighbor:您能描述一下
Map
键的分布吗?另外,如果你看不到
Map
方法的计时有任何变化,你有没有试着找出减速的原因?@Peter Lawrey当然,在一个线程中只使用ConcurrentHashMap将提供纳秒延迟的巨大吞吐量。正如我所说,使用ConcurrentHashMap不是唯一的活动。也为了