Если Вы хотите стать немного более техническими о том, что энергозависимое ключевое слово делает, рассматривает следующей программой (я использую DevStudio 2005):
#include <iostream>
void main()
{
int j = 0;
for (int i = 0 ; i < 100 ; ++i)
{
j += i;
}
for (volatile int i = 0 ; i < 100 ; ++i)
{
j += i;
}
std::cout << j;
}
Используя оптимизированный стандарт (выпускают) параметры компилятора, компилятор создает следующий ассемблер (IA32):
void main()
{
00401000 push ecx
int j = 0;
00401001 xor ecx,ecx
for (int i = 0 ; i < 100 ; ++i)
00401003 xor eax,eax
00401005 mov edx,1
0040100A lea ebx,[ebx]
{
j += i;
00401010 add ecx,eax
00401012 add eax,edx
00401014 cmp eax,64h
00401017 jl main+10h (401010h)
}
for (volatile int i = 0 ; i < 100 ; ++i)
00401019 mov dword ptr [esp],0
00401020 mov eax,dword ptr [esp]
00401023 cmp eax,64h
00401026 jge main+3Eh (40103Eh)
00401028 jmp main+30h (401030h)
0040102A lea ebx,[ebx]
{
j += i;
00401030 add ecx,dword ptr [esp]
00401033 add dword ptr [esp],edx
00401036 mov eax,dword ptr [esp]
00401039 cmp eax,64h
0040103C jl main+30h (401030h)
}
std::cout << j;
0040103E push ecx
0040103F mov ecx,dword ptr [__imp_std::cout (40203Ch)]
00401045 call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (402038h)]
}
0040104B xor eax,eax
0040104D pop ecx
0040104E ret
Рассмотрение вывода, компилятор решил использовать регистр ecx для хранения значения j переменной. Для энергонезависимого цикла (первое) компилятор присвоил меня регистру eax. Довольно простой. Существует несколько интересных битов, хотя - lea ebx, [ebx] инструкция является эффективно многобайтовой инструкцией по NOP так, чтобы переходы цикла к 16 байтам выровняли адрес памяти. Другой использование edx для постепенного увеличения счетчика цикла вместо того, чтобы использовать inc eax инструкция. Добавление reg, reg инструкция имеет более низкую задержку на нескольких ядрах IA32 по сравнению с inc reg инструкция, но никогда не имеет более высокую задержку.
Теперь для цикла с энергозависимым счетчиком цикла. Счетчик хранится в [ESP], и энергозависимое ключевое слово говорит компилятору, что значение должно всегда читаться из к памяти и никогда не присваиваться регистру. Компилятор даже идет, насколько не сделать загрузку/инкремент/хранилище как три отличных шага (загрузите eax, inc eax, сохраните eax) при обновлении встречного значения вместо этого память непосредственно изменяется в единственной инструкции (добавить мадам, reg). Путем код был создан, гарантирует, что значение счетчика цикла всегда актуально в контексте единственного ядра процессора. Никакая операция на данных не может привести к повреждению или потере данных (следовательно не использующий load/inc/store, так как значение может измениться во время inc, таким образом потерянного на хранилище). Так как прерывания могут только быть обслужены, как только текущая команда завершилась, данные никогда не могут повреждаться, даже с невыровненной памятью.
, Как только Вы представляете второй ЦП системе, энергозависимое ключевое слово не примет меры против данных, обновляемых другим ЦП одновременно. В вышеупомянутом примере Вам были бы нужны данные, которые будут не выровнены для получения потенциального повреждения. Энергозависимое ключевое слово не предотвратит потенциальное повреждение, если данные не могут быть обработаны атомарно, например, если бы счетчик цикла имел тип, долго длинный (64 бита) тогда, то это потребовало бы два 32 битовых операции обновлять значение, посреди которого прерывание может произойти и изменить данные.
Так, энергозависимое ключевое слово только хорошо для выровненных данных, которые меньше чем или равны размеру собственных регистров, таким образом, что операции являются всегда атомарными.
энергозависимое ключевое слово было задумано, чтобы использоваться с операциями IO, где IO будет постоянно изменять, но имел базовый адрес, такой как устройство UART с отображенной памятью, и компилятор не должен продолжать снова использовать первое значение, считанное из адреса.
, Если Вы обрабатываете большие данные или имеете несколько центральных процессоров тогда, Вам будет нужен более высокий уровень (ОС) запирающая система для обработки доступа к данным правильно.
Я думаю, что вы удаляете элементы массива с помощью оператора delete
.
Этот оператор удаляет элемент по указанному вами индексу, но длина массива не изменяется, например:
var a = [1,2,3];
delete a[0];
console.log(a); // results in [undefined, 2, 3]
Если вы хотите удалить элементы и сдвинуть индексы, вы можете использовать функцию splice :
var a = [1,2,3];
a.splice(0,1);
console.log(a); // [2, 3]
Вы можете реализовать простую функцию для удаления элементов в заданный индекс:
Array.prototype.removeAt = function (index) {
this.splice(index,1);
};
Джон Ресиг (автор jQuery) написал функцию, которая (действительно) удаляет элементы из массива в Javascript. Если вы используете эту функцию вместо оператора удаления, вы должны получить точное количество из массива после удаления.