private InstrumentInfo[] instrumentInfos = new InstrumentInfo[Constants.MAX_INSTRUMENTS_NUMBER_IN_SYSTEM];
public void SetInstrumentInfo(Instrument instrument, InstrumentInfo info)
{
if (instrument == null || info == null)
{
return;
}
instrumentInfos[instrument.Id] = info; // need to make it visible to other threads!
}
public InstrumentInfo GetInstrumentInfo(Instrument instrument)
{
return instrumentInfos[instrument.Id]; // need to obtain fresh value!
}
SetInstrumentInfo
и GetInstrumentInfo
вызываются из разных потоков.
InstrumentInfo
является неизменным классом.
Могу ли я получить самую последнюю копию при вызове GetInstrumentInfo
? Боюсь, что я могу получить "кэшированную" копию. Должен ли я добавить некоторую синхронизацию?
Объявление instrumentInfos
как volatile
не помогло, потому что мне нужно объявлять элементы массива как volatile
, а не сам массив.
У моего кода есть проблемы, и если да, то как его исправить?
UPD1:
Мне нужен мой код для работы в реальной жизни, чтобы он не соответствовал всем спецификациям! Так что, если мой код работает в реальной жизни, но не будет работать "теоретически" на каком-то компьютере в какой-то среде - это нормально!
- Мне нужен мой код для работы на современном сервере X64 (в настоящее время 2 процессора HP DL360p Gen8) под Windows с использованием последней .NET Framework.
- Мне не нужно работать с моим кодом под странными компьютерами или Mono или что-то еще
- Я не хочу вводить латентность, поскольку это программное обеспечение HFT. Так как "реализация Microsoft использует сильную модель памяти для записи. Это означает, что записи обрабатываются так, как будто они были изменчивыми". Вероятно, мне не нужно добавлять дополнительные
Thread.MemoryBarrier
, которые не будут делать ничего, кроме добавления задержки. Я думаю, мы можем полагаться на то, что Microsoft продолжит использовать "сильную модель памяти" в будущих выпусках. По крайней мере, маловероятно, что Microsoft изменит модель памяти. Поэтому допустим, что этого не произойдет.
UPD2:
Самое последнее предложение - использовать Thread.MemoryBarrier();
. Теперь я не понимаю точных мест, где я должен вставить его, чтобы моя программа работала в конфигурации стандартной (x64, Windows, Microsoft.NET 4.0). Помните, что я не хочу вставлять строки "просто для запуска вашей программы на IA64 или .NET 10.0". Для меня важнее скорость, чем переносимость. Однако было бы интересно также обновить мой код, чтобы он работал на любом компьютере.
UPD3
Решение .NET 4.5:
public void SetInstrumentInfo(Instrument instrument, InstrumentInfo info)
{
if (instrument == null || info == null)
{
return;
}
Volatile.Write(ref instrumentInfos[instrument.Id], info);
}
public InstrumentInfo GetInstrumentInfo(Instrument instrument)
{
InstrumentInfo result = Volatile.Read(ref instrumentInfos[instrument.Id]);
return result;
}