2009-09-19 3 views
1

Я хочу изменить этот код на код сборки, работая на mac, как это сделать?Как написать этот код с кодом сборки?

while (a --) 
{ 
    *pDest ++ += *pSrC++; 
} 
+2

Зачем вы хотите это сделать? У вас есть доказательства того, что компилятор не создает оптимизированный код для этого блока? –

+1

Intel Mac или PPC (что gen)? Я не знаю сборки, но достаточно знаю, что сборка x86 и PPC будет отличаться. – UnkwnTech

+1

Это intel mac, и на iPhone. Я работаю над программой, которая использует этот код в потоке, и поток всегда делает такие вещи, иногда он застревает, поэтому мне интересно, потому что это слишком тяжело для iPhone. – Yuhui

ответ

2

Так что это за руку? (Iphone?).Каков размер этих указателей (байты, полуслова, слова и т. Д.?), У вас проблемы с выравниванием (копирование слов на границе без слов)? Если это байты, то да, сгенерированный код, вероятно, очень медленный, оптимизатор не может слишком много работать с ним. Где это вас покидает? Вы получаете то, что получаете.

Вот пример:

mov ip, #0 
.L3: 
    ldrb r3, [r0, ip] @ zero_extendqisi2 
    ldrb r2, [r1, ip] @ zero_extendqisi2 
    add r3, r3, r2 
    strb r3, [r1, ip] 
    add ip, ip, #1 
    cmp ip, r4 
    bne .L3 

Потому что ваш код имел указатели подсчитывая, компилятор добавил инструкцию, оно не потребность.

sub  ip, rx, #1 
.L3: 
    ldrb r3, [r0, ip] @ zero_extendqisi2 
    ldrb r2, [r1, ip] @ zero_extendqisi2 
    add r3, r3, r2 
    strb r3, [r1, ip] 
    subs ip, ip, #1 
    bne .L3 

Поскольку бит переноса не используется Интересно, если есть способ загрузки слова и сделать слово на основе добавляет, делая одно слово в то время.

load 0xnnmmoopp 
load oxqqrrsstt 

маскировать один из них не гарантирует никаких проблем нести

0xnnmmoopp -> 0xn0mmo0pp

добавить

0xgghhiikk = 0xn0mmo0pp + 0xqqrrsstt

затем хранить чч и кк как байт

Вы должны вернуться к оригиналу inal cripple, mm и pp bytes повторно добавляют и сохраняют gg и ii байты.

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

Вам нужно будет сэкономить много регистров в стеке, так что это будет стоить вам там, поэтому вы не захотите делать это при небольших значениях (менее 10 разрешений).

В любом случае, о чем подумать. Просто удаление одной строки кода в asm выше должно быть заметно для длинных прогонов.

EDIT:

На самом деле, что модификация я сделал на выходе компилятора был сломан. Это больше похоже на:

mov ip, ra 
.L3: 
    subs ip, ip, #1 
    ldrb r3, [r0, ip] 
    ldrb r2, [r1, ip] 
    add r3, r3, r2 
    strb r3, [r1, ip] 
    bne .L3 
+0

Спасибо большое, я ценю всех парней здесь, я многому учу от вас. – Yuhui

2

Фактические инструкции ассемблера будут отличаться, но вот псевдокод, который можно легко перевести на ассемблер.

Обратите внимание, что * 4 - это потому, что я предполагаю, что вы передаете ints. Он будет меняться в зависимости от размера передаваемых данных.

incrementor = 0 ;really easy 
top: 
jump to bottom if a equals 0  ;jump if zero is the intel instruction here. 
memoryDest[incrementor*4] = memorySrc[incrementor*4] ;this will be a bit messy, you'll probably need some temp variables 
incrementor += 1 ;dead easy 
jump to top: ;goto. PLEASE DON'T CITE 'CONSIDERED HARMFUL`, THIS IS ASM!!!!11ONEONE 
bottom: 
+0

Спасибо, но можете ли вы перевести его в код сборки GNU?Я не очень хорошо знаком с этим. – Yuhui

+2

@Yuhui, если вы не хотите использовать свои усилия для своего собственного проекта, я даже менее готов использовать свои усилия для вашего проекта. Вы хотя бы * пробовали *? – strager

+0

Да, я пробовал, и я действительно не знаю, как начать. Мне очень жаль, что у меня нет опыта сборки ... – Yuhui

0

Вы говорите, что разрабатываете для iPhone и пытаетесь улучшить скорость. Похоже, вы пытаетесь скопировать блок памяти, для которого вы, вероятно, захотите использовать memcpy(dest, src, size).

+0

Прошу прощения, я хочу это * pDest ++ + = * pSrc, ранее сделанный неверный паст. Значит, для этого любая идея сделать это быстрее? – Yuhui

+1

Нет, код у вас самый быстрый. Скорее всего, если ваши массивы не будут огромными, это не будет узким местом. Это может помочь, если вы предоставили немного больше контекста вашей проблеме. –

6

Это intel mac, и на iPhone. Я работаю над программой, которая использует этот код в потоке, и поток всегда делает такие вещи, иногда он застревает, поэтому мне интересно, связано ли это с тем, что вычисление слишком сильно для iPhone.

Нет, ваша проблема не имеет отношения к этому коду. Пусть компилятор выполнит свою работу и оптимизирует это. Ваша проблема в другом месте. Похоже, у вас есть состояние гонки или взаимоблокировка между потоками. Я не могу психически отлаживать вашу проблему без дополнительной информации, но я могу сказать, что вы лаяете неправильное дерево.

2

Предполагая, что рассматриваемые массивы имеют разумную длину и в зависимости от типов pDest и pSrc, вы можете получить разумное ускорение на этом, используя инструкции NEON на ARMv7 (iPhone 3GS и новый Touch) и с помощью SSE на Intel.

Конкретный код и степень ускорения, которую вы можете получить, будут зависеть от типа данных в исходном и целевом массивах, о том, какое выравнивание гарантирует наличие адресов массива, а также то, что распределение типичных длин в массивы подобны.

Как всегда, ничто из этого не стоит делать, если у вас нет следа Shark, показывающего, что этот цикл является заметной частью вашего времени выполнения. Если вы выполняете настройку производительности на уровне приложений на Mac или iPhone, и вы не используете Shark или Instruments, вы делаете это неправильно.

Если массивы являются плавающей точкой, вы можете получить хорошо настроенный векторный код на Intel mac, включив Accelerate.framework и используя функцию vDSP_vadd(). Нет необходимости в сборке.

Если у вас есть доступ к переговорам WWDC 2008, Эрик Postpischil дал хороший разговор об основных методах векторизации, в которой он шел через пишущий вектор код для обработки именно этот цикл (в том случае, когда КИЕ и pDest является одно- прецизионных массивов) на Intel, хотя для простоты он использовал C с векторными встроенными функциями вместо ASM.

1

Несколько stackshots покажут, действительно ли это место, где вы проводите время.

Если, разворачивая цикл может помочь, как:

while (a >= 8){ 
    pDest[0] += pSrc[0]; 
    pDest[1] += pSrc[1]; 
    pDest[2] += pSrc[2]; 
    pDest[3] += pSrc[3]; 
    pDest[4] += pSrc[4]; 
    pDest[5] += pSrc[5]; 
    pDest[6] += pSrc[6]; 
    pDest[7] += pSrc[7]; 
    pDest += 8; 
    pSrc += 8; 
    a -= 8; 
} 
// followed by your loop 

Вы можете написать код на ассемблере, но это, вероятно, не было бы намного лучше.

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