2013-09-23 2 views
1

Я написал следующий тест JavaОптимизация процессором Sandy-Bridge?

public class NegativeTest { 

/** 
* @param args 
*/ 
public static void main(String[] args) { 

    long start = System.currentTimeMillis(); 

    int value = 12345; 
    for (int j = 0; j < 30; j++) { 
     for (int i = 0; i < 1000000000; i++) { 
      value = value * -1 - i; 
     } 
    } 

    System.out.println(System.currentTimeMillis() - start); 

    //to avoid compilation optimization 
    System.out.println(value); 
} 
} 

потребовался около 1,3 второго закончить на моем Intel (R) сердцевина (TM) i5-3210M (Ivy-Bridge) машина, однако после того, как я изменил линию

= значение * -1 - я

к

значение = значение - я,

После этого потребовалось около 10 sencond до конца (примерно в 10 раз больше, чем в предыдущей версии)!

Когда я запустил этот тест на других не Sandy Bridge процессоров, результат полностью меняется: = значение * -1 - я версия занимает в два раза длиннее на = значение - я версия делает !

Может ли кто-нибудь объяснить эту разницу? Связано ли это с каким-либо конкретным проектом оптимизации в архитектуре Sandy Bridge?

+0

Ну, это интересно. Когда я пробую это на C++, я получаю 0 секунд для первого случая и 7,472 секунды для второго. Кажется, что в первом случае моему компилятору C++ удается полностью оптимизировать цикл в одном значении. Таким образом, это в основном сводится к оптимизации компилятора.Возможно, Java JIT делает что-то другое для SB. (о, и я тестировал его на машине Sandy Bridge) – Mysticial

+0

@Mysticial Пробовал ли вы это на не-песчаной машине? – njzhxf

+0

Это не имело бы значения. Потому что мой компилятор C++ оптимизировал первый случай по существу «print (« - 2115085767 »)». Это будет работать в нулевое время на любом процессоре. – Mysticial

ответ

1

я сделал попробовать то же самое на C# .Net 4.6 x64

1) 16239ms

2) 8175ms

теперь, если я смотрю разборки диф:

1)

value = value * -1 - i; 
000007FE9958422A neg   edx 
000007FE9958422C sub   edx,eax 

2)

value = value - i; 
000007FE995842A2 sub   edi,eax 

У меня есть i7 4790K.

Если я использую двойным/плывут вместо целой разборки содержит скалярную AVX код, который может быть быстрее:

value = value * -1 - i; 
000007FE9957422B vmulsd  xmm0,xmm0,mmword ptr [7FE99574298h] 
000007FE99574234 vcvtsi2sd xmm1,xmm1,eax 
000007FE99574239 vsubsd  xmm0,xmm0,xmm1 

Так что теперь это было бы смешно использовать AVX 2.0 для целого числа.

Edit:

Когда я пытаюсь это в C++, я получаю 0 секунд

на самом деле это троллинг :)

Обратите внимание, бенчмаркинг не просто, вам нужно тщательно разобрать разборку, использовать точные счетчики, обеспечить, чтобы CPU не был в режиме сбалансированной энергии, приоритет приложения и т. д.

Смежные вопросы